use strict;
use warnings;
use 5.014;

package App::palien 0.16 {

use Getopt::Long qw( GetOptions );
use Pod::Usage qw( pod2usage );
use Path::Tiny qw( path );

# ABSTRACT: Command line interface to Alien::Base
# VERSION


sub _version ($)
{
  my($alien) = @_;
  my $class = ref $alien;
  eval qq{ \$$class\::VERSION };
}

sub _modversion ($)
{
  my($alien) = @_;
  return $alien->version if $alien->can('version');
  return 'unknown' unless $alien->can('config');
  my $ver = $alien->config('version');
  chomp $ver;
  $ver;
}

sub _bin_dir
{
  my($dir_sep, $alien) = @_;

  join( $dir_sep, $alien->bin_dir );
}

sub _cflags ($)
{
  my($alien) = @_;
  scalar $alien->cflags;
}

sub _libs ($)
{
  my($alien) = @_;
  scalar $alien->libs;
}

sub main
{
  local(undef, @ARGV) = @_;
  
  my $bin_dir;
  my $dir_sep = ' ';
  my $cflags;
  my $libs;
  my $list;
  my $dll;
  my $modversion;
  my $detail;
  my $status = 0;
  
  GetOptions(
    "bin-dir"    =>   \$bin_dir,
    "dir-sep"    =>   \$dir_sep,
    "cflags"     =>   \$cflags,
    "libs"       =>   \$libs,
    "dll"        =>   \$dll,
    "modversion" =>   \$modversion,
    "detail|d"   =>   \$detail,
    "help|h"     =>   sub { pod2usage({ -verbose => 2}) },
    "version"    =>   sub { print "App::palien version " . ($App::palien::VERSION || 'dev') . "\n"; exit 1; },
  ) || pod2usage(1);

  unless(@ARGV)
  {
    my %mods;
    foreach my $inc (@INC)
    {
      my $dir = path( "$inc/Alien" );
      next unless -d $dir;
      foreach my $pm (grep /\.pm$/, map { $_->basename } grep { -f $_ } $dir->children)
      {
        $pm =~ s/\.pm$//;
        next if $pm =~ /^(Base|Packages|Builder|MSYS)$/;
        print "$pm = $pm\n";
        $mods{"Alien::$pm"} = 1;
      }

      my $share_root = path("$inc/auto/share/dist");
      next unless -d $share_root;
      foreach my $share (sort { $a->basename cmp $b->basename } $share_root->children)
      {
        my $readme = $share->child('README');
        next unless (-r $readme) && ($readme->slurp =~ /This README file is autogenerated by Alien::Base/);
        my $module = $share->basename;
        $module =~ s/-/::/g;
        $mods{$module} = 1;
      }

    }
    
    @ARGV = sort keys %mods;
  }

  foreach my $module (@ARGV)
  {
    my $alien;
  
    if($module =~ /::/)
    {
      $alien = eval qq{ require $module; $module->new };
      if($@)
      {
        warn "unable to load $module: $@";
        $status = 2;
        next;
      }
    }
    else
    {
      $alien = _find($module);
      next unless $alien;
    }
    
    if($detail)
    {
      my $class = ref $alien;
      printf "=============================================\n";
      printf "class:      %s\n", ref $alien;
      printf "version:    %s\n", _version $alien;
      printf "modversion: %s\n", _modversion $alien;
      printf "dist:       %s\n", $alien->dist_dir if eval { $alien->dist_dir };
      printf "cflags:     %s\n", _cflags $alien;
      printf "libs:       %s\n", _libs $alien;
    }
    
    if( defined $bin_dir)
    {
      print _bin_dir ( $dir_sep, $alien) , "\n";
    }
    
    if($cflags)
    {
      print _cflags $alien, "\n";
    }
    
    if($libs)
    {
      print _libs $alien, "\n";
    }
    
    if($modversion)
    {
      print _modversion $alien, "\n";
    }
    
    if($dll)
    {
      print $_, "\n" for $alien->dynamic_libs;
    }
  }
  
  $status;
}

my $byname;

sub _find
{
  my($q) = @_;

  unless($byname)
  {
    $byname->{libarchive} = 'Alien::Libarchive';
    $byname->{bz2}        = 'Alien::bz2';
    foreach my $inc (@INC)
    {
      my $share_root = path("$inc/auto/share/dist");
      next unless -d $share_root;
      foreach my $share ($share_root->children)
      {
        my $readme = $share->child('README');
        next unless (-r $readme) && ($readme->slurp =~ /This README file is autogenerated by Alien::Base/);
        my $module = $share->basename;
        $module =~ s/-/::/g;
        my $name = eval qq{ require $module\::ConfigData; $module\::ConfigData->config('name'); };
        $byname->{$name} = $module;
      }
    }
  }
  
  my $module = $byname->{$q};
  
  defined $module ? eval qq{ require $module; $module->new } || warn "unable to load $module: $@" && () : ();
}

}

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

App::palien - Command line interface to Alien::Base

=head1 VERSION

version 0.16

=head1 DESCRIPTION

This module provides the machinery for the command line
program L<palien>.

=head1 SEE ALSO

L<palien>

=head1 AUTHOR

Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>

Contributors:

Diab Jerius (DJERIUS)

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2017 by Graham Ollis.

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

=cut
