package Tak::Script;

use Getopt::Long qw(GetOptionsFromArray :config posix_defaults bundling);
use Config::Settings;
use IO::Handle;
use Moo;

has options => (is => 'ro', required => 1);
has env => (is => 'ro', required => 1);

has stdin => (is => 'lazy');
has stdout => (is => 'lazy');
has stderr => (is => 'lazy');

sub _build_stdin { shift->env->{stdin} }
sub _build_stdout { shift->env->{stdout} }
sub _build_stderr { shift->env->{stderr} }

has config => (is => 'lazy');

sub _build_config {
  my ($self) = @_;
  Config::Settings->new->parse_file(
    $self->options->{config} || '.tak/default.conf'
  );
}

sub BUILD {
  shift->setup_logger;
}

sub setup_logger { }

sub _parse_options {
  my ($self, $string, \@argv) = @_;
  my @spec = split ';', $string;

sub run {
  my ($self) = @_;
  my @argv = @{$self->env->{argv}};
  unless (@argv && $argv[0]) {
    return $self->local_help;
  }
  my $cmd = shift(@argv);
  if (my $code = $self->can("local_$cmd")) {
    return $self->_run($cmd, $code, @argv);
  } elsif ($code = $self->can("each_$cmd")) {
    return $self->_run_each($cmd, $code, @argv);
  }
  $self->stderr->print("No such command: ${cmd}\n");
  return $self->local_help;
}

sub _load_file {
  my ($self, $file) = @_;
  $self->_load_file_in_my_script($file);
}

sub local_help {
  my ($self) = @_;
  $self->stderr->print("Help unimplemented\n");
}

sub _run_local {
  my ($self, $cmd, $code, @argv) = @_;
  my $opt = do {
    if (my $proto = prototype($code)) {
      $self->_parse_options($proto, \@argv);
    } else {
      {};
    }
  };
  $self->$code($opt, @argv);
}

1;
