use strict;
use warnings;

package Footprintless::App::ActionCommand;
$Footprintless::App::ActionCommand::VERSION = '1.12';
use Carp;
use Footprintless::App -command;
use Getopt::Long::Descriptive;

sub _action {
    my ( $self, $action_name ) = @_;
    my $action = $self->_action_implementation($action_name)
        || croak("invalid action [$action_name]");

    unless ( ref($action) ) {
        { eval "require $action" };    ## no critic
        $action = $action->new();
    }

    return $action;
}

sub _action_args {
    my ( $self, $action, @action_args ) = @_;

    local @ARGV = @action_args;
    my ( $options, $usage ) = describe_options( $action->usage_desc(), $action->opt_spec() );
    return ( $usage, $options, \@ARGV );
}

sub _action_implementation {
    croak( ref( $_[0] ) . ' must implement _action_implementation' );
}

sub execute {
    my ( $self, $opts, $args ) = @_;

    $self->{action}->execute(
        $self->{footprintless}, $self->{coordinate},
        $self->{action_opts},   $self->{action_args}
    );
}

sub opt_spec {
    return ( [ "log=s", "will set the log level", ], );
}

sub validate_args {
    my ( $self, $opts, $args ) = @_;

    $self->{footprintless} = $self->app()->footprintless();

    my ( $coordinate, $action_name, @action_args ) = @$args;
    croak("coordinate required") unless ($coordinate);
    croak("action required")     unless ($action_name);

    $self->{coordinate} = $coordinate;
    $self->{action}     = $self->_action($action_name);
    ( $self->{action_usage}, $self->{action_opts}, $self->{action_args} ) =
        $self->_action_args( $self->{action}, @action_args );

    $self->{action}->validate_args(
        $self->{footprintless}, $self->{coordinate},
        $self->{action_opts},   $self->{action_args}
    );
}

1;

__END__

=pod

=head1 NAME

Footprintless::App::ActionCommand

=head1 VERSION

version 1.12

=head1 AUTHOR

Lucas Theisen <lucastheisen@pastdev.com>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2016 by Lucas Theisen.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=head1 SEE ALSO

Please see those modules/websites for more information related to this module.

=over 4

=item *

L<Footprintless|Footprintless>

=back

=cut
