#!perl

use strict;
use warnings;
use feature qw( say );

use App::perlimports::ExportInspector ();
use Getopt::Long::Descriptive qw( describe_options );
use List::Util qw( max );
use Log::Dispatch ();
use Module::Runtime qw( use_module );
use Pod::Usage qw( pod2usage );
use Text::SimpleTable::AutoWidth ();

my ( $opts, $usage ) = _options();

if ( $opts->version ) {
    say $App::perlimports::ExportInspector::VERSION;
    exit(0);
}

if ( $opts->help ) {
    print $usage;
    exit(0);
}

if ( $opts->verbose_help ) {
    print STDOUT $usage;
    pod2usage({ -exitval => 0 });
}

if ( $opts->libs ) {
    unshift @INC, ( split m{,}, $opts->libs );
}

my $logger = Log::Dispatch->new(
    outputs => [
        [
            'Screen',
            min_level => $opts->log_level,
            newline   => 1,
            stderr    => 1
        ]
    ]
);

my $module = $opts->module || shift @ARGV;

if ( !$module ) {
    say q{Mandatory parameter 'module' missing};
    print $usage;
    exit(1);
}

my $ei = App::perlimports::ExportInspector->new(
    logger      => $logger,
    module_name => $module,
);

if ( $ei->is_oo_class ) {
    print 'Appears to be an Object Oriented class.' . "\n";
}

if ( @{ $ei->class_isa } ) {
    my $t = Text::SimpleTable::AutoWidth->new();
    $t->captions( ['ISA'] );
    for my $class ( @{ $ei->class_isa } ) {
        $t->row($class);
    }
    print $t->draw;
}

if ( @{ $ei->pkg_isa } ) {
    my $t = Text::SimpleTable::AutoWidth->new();
    $t->captions( ['Package ISA'] );
    for my $class ( @{ $ei->pkg_isa } ) {
        $t->row($class);
    }
    print $t->draw;
}

if ( @{ $ei->at_export_tags } ) {
    my %tags = %{ $ei->at_export_tags };
    my @keys = keys %tags;

    my @headings = ( 'Export Tag', 'Exported Symbols' );

    my $col1_width = max map { length($_) } @keys, $headings[0];
    my $col2_width = max map { length($_) } map ( { @{$_} } values %tags ),
        $headings[1];

    my $t = Text::SimpleTable->new(
        [ $col1_width, 'Export Tag' ],
        [ $col2_width, 'Exported Symbols' ]
    );

    my $i = 0;
    for my $key ( sort @keys ) {
        $t->row( $key, join "\n", sort @{ $tags{$key} } );
        ++$i;
        $t->hr if $i < scalar @keys;
    }
    print $t->draw;
}

if ( @{ $ei->at_export_fail } ) {
    my $t = Text::SimpleTable::AutoWidth->new();
    $t->captions( ['@EXPORT_FAIL'] );
    for my $val ( sort @{ $ei->at_export_fail } ) {
        $t->row($val);
    }
    print $t->draw;
}

if ( $ei->has_implicit_exports ) {
    my $t = Text::SimpleTable::AutoWidth->new();
    if ( $ei->implicit_export_names_match_values ) {
        $t->captions( ['Default Exported Symbols'] );
        for my $symbol ( sort $ei->implicit_export_names ) {
            $t->row($symbol);
        }
    }
    else {
        $t->captions( [ 'Default Export Symbol', 'Import Name' ] );
        for my $key ( sort $ei->implicit_export_names ) {
            $t->row( $key, $ei->implicit_exports->{$key} );
        }
    }
    print $t->draw;
    printf( "%i symbols\n", scalar $ei->implicit_export_names );
}

my $exports = $ei->explicit_exports;
if ( !keys %{$exports} ) {
    print 'No exported symbols found' . "\n";
    exit(0);
}

{
    my $t = Text::SimpleTable::AutoWidth->new();

    if ( $ei->explicit_export_names_match_values ) {
        $t->captions( ['All Exportable Symbols'] );
        for my $symbol ( sort $ei->explicit_export_names ) {
            $t->row($symbol);
        }
    }
    else {
        $t->captions( [ 'Explicit Export Symbol', 'Import Name' ] );
        for my $key ( sort $ei->explicit_export_names ) {
            $t->row( $key, $exports->{$key} );
        }
    }
    print $t->draw;
    printf( "%i symbols\n", scalar $ei->explicit_export_names );

    require Data::Dumper; ## no perlimports
    $logger->debug( Data::Dumper::Dumper($ei) );
}

sub _options {
    return describe_options(
        'dump-perl-exports %o',
        [
            'module|m=s', 'The module to inspect for exports',
        ],
        [],
        [
            'libs=s',
            'Comma-separated list of library paths to include (eg --libs lib,t/lib,dev/lib)',

        ],
        [],
        [ 'version', 'Print installed version', { shortcircuit => 1 } ],
        [
            'log-level|l=s', 'Print messages to STDERR',
            { default => 'warning' }
        ],
        [ 'help', "Print usage message and exit", { shortcircuit => 1 } ],
        [
            'verbose-help', "Print usage message and documentation ",
            { shortcircuit => 1 }
        ],
    );
}

# PODNAME: dump-perl-exports
# ABSTRACT: A command line utility for describing what a class exports

__END__

=pod

=encoding UTF-8

=head1 NAME

dump-perl-exports - A command line utility for describing what a class exports

=head1 VERSION

version 0.000035

=head1 SYNOPSIS

Here are a few interesting modules to help you understand the output of
C<dump-perl-exports>.

    dump-perl-exports POSIX

    dump-perl-exports Getopt::Long

    dump-perl-exports Getopt::Long::Descriptive

    dump-perl-exports Test::More

    dump-perl-exports Test::Most

    dump-perl-exports Moose

    dump-perl-exports Moo

=head1 AUTHOR

Olaf Alders <olaf@wundercounter.com>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2020 by Olaf Alders.

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
