#!/usr/bin/env perl
# -*- mode: perl; coding: utf-8 -*-
use strict;
use warnings qw(FATAL all NONFATAL misc);
use constant DEBUG_LIB => $ENV{DEBUG_YATT_CLI_LIB};
use FindBin; BEGIN {
  if (-r (my $libFn = "$FindBin::RealBin/libdir.pl")) {
    print STDERR "# using $libFn\n" if DEBUG_LIB;
    do $libFn
  }
  elsif ($FindBin::RealBin =~ m{/local/bin$ }x) {
    print STDERR "# using local/lib/perl5\n" if DEBUG_LIB;
    require lib;
    lib->import($FindBin::RealBin . "/../lib/perl5");
  }
  else {
    print STDERR "# No special libdir\n" if DEBUG_LIB;
  }
}

sub MY () {__PACKAGE__}
#----------------------------------------
use 5.010;

use base qw/YATT::Lite::Object/;
use YATT::Lite::MFields
  (()
   , [cf_help => doc => "show help messages"]
   , [cf_script_path => doc => "script search path for yatt subcommands"]
   , [cf_debug => doc => "run in perldebugger"]
  );
# XXX: Should use doc strings in help message.

use YATT::Lite;
use YATT::Lite::Util::CmdLine qw/parse_opts/;
use List::Util qw/uniq/;

{
  my MY $self = MY->new(MY->parse_opts(\@ARGV, undef, {h => "help", d => "debug"}));

  my $cmd = shift // 'help';

  if (my $sub = $self->can("cmd_$cmd")) {
    $sub->($self, @ARGV);
  } elsif (my $fn = $self->subcmd_path($cmd)) {
    if ($self->{cf_debug}) {
      exec $^X, "-d", $fn, @ARGV or die "couldn't exec $fn: $!";
    } else {
      exec $fn, @ARGV or die "couldn't exec $fn: $!";
    }
  } else {
    $self->usage("No such command: $cmd");
  }
}

sub usage {
  (my MY $self, my $message) = @_;
  print STDERR "$message\n" if $message;
  $self->cmd_help;
}

sub cmd_help {
  my MY $self = shift;
  print STDERR <<END;
Usage: @{[File::Basename::basename $0]} [--option=value] <command> [<args>]

Available commands are:
END

  print STDERR "  ", join("\n  ", $self->subcmd_list), "\n";
  exit 1;
}

sub subcmd_list {
  (my MY $self) = @_;
  my $prefix = "$self->{cf_script_path}yatt";
  my %hidden; $hidden{$_} = 1
    for qw(backend call command dispatcher
           lintany lintpm lintrc
           xgettext xhftest);
  grep {
    not $hidden{$_}
  }
  uniq sort map {
    my $rest = substr($_, length($prefix));
    if ($rest =~ s/^\.//) {
      $rest;
    } elsif ($rest =~ /^-([-\w]+)/) {
      $1;
    } else {
      ();
    }
  }
  grep {-x}
  glob("$prefix*");
}

sub subcmd_path {
  (my MY $self, my $subcmd) = @_;
  foreach my $fnPat (qw(yatt-%s*  yatt.%s)) {
    my $glob = $self->{cf_script_path}. sprintf($fnPat, $subcmd);
    foreach my $fn (glob($glob)) {
      return $fn if -x $fn;
    }
  }
}

sub find_libdir {
  shift;
  my $pm = 'YATT/Lite.pm';
  substr($INC{$pm}, 0, -1-length($pm));
}

sub after_new {
  (my MY $self) = @_;
  $self->{cf_script_path} //= do {
    if ($FindBin::RealBin =~ m{/YATT/scripts\z}) {
      $self->find_libdir . "/YATT/scripts/"
    } else {
      $FindBin::Bin . "/";
    }
  };
}
