#!/usr/bin/env perl

use 5.012_005;
my $pVer = version->parse('5.012_005');

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

our $VERSION = "0.01";
use List::Util qw(first);
use FastGlob qw(glob);
use Getopt::Long;
use version 0.77;

use lib 'lib';
use App::findeps;

my $usage = <<"EOL";
Usage: $0 [ -s ] [ -L yourlib ] FILE | cpanm
  -u | --upgradeAll : set it if you want to upgrade your dependencies
  -L | --myLib      : defaults to 'lib'

EOL

GetOptions(
    "u|upgradeAll"   => \$App::findeps::Upgrade,
    "L|myLib=s"      => \$App::findeps::myLib,
    "m|makeCpanfile" => \$App::findeps::toCpanfile,
) or die $usage;

die $usage unless @ARGV;

makeCpanfile(@ARGV) if $App::findeps::toCpanfile;

my @list = scan(@ARGV);

die "Ready to run @ARGV\n" unless @list;

say $_ for @list;

exit;

sub scan {
    my @files = @_;
    my $map   = App::findeps::scan( files => \@files );
    my @list  = ();
    foreach my $key ( sort keys %$map ) {
        next if $key =~ /\.pl$/;
        my $version = $map->{$key};
        my $name    = _name($key);
        my $dist    = $name;
        $dist .= "~$version" if length $version;
        push @list, $dist;
    }
    return @list;
}

sub makeCpanfile {
    die 'Too many Arguments' if @_ > 1;
    my $file = shift;
    my $name = _name($file);
    if ( $file =~ /::/ ) {
        $file = $name;
        $file =~ s!::!/!g;
        $file = "lib/$file.pm";
    }
    my @list = scan($file);
    my ( @require, @test_require );
    push @require, make_line($_) for @list;
    for my $test ( scan( &glob('t/*.t') ) ) {
        push @test_require, make_line($test) unless first { $test =~ /^$_/ } @list, $name;
    }
    local $" = "";
    print <<"EOL";
requires 'perl', '$pVer';

@require
EOL
    local $" = "    ";
    print <<"EOL" if @test_require;
on 'test' => sub {
    @test_require};
EOL
    exit;
}

sub make_line {
    my ( $name, $version ) = split '~', shift;
    my $res = qx"corelist $name";
    $version = $version ? ", '$version'" : '';
    $res =~ /5.(\d+)/;
    return "requires '$name'$version;\n"
        if $res =~ /$name was not in CORE/
        or $1 and version->parse($1) > $pVer;
    return;
}

sub _name {
    my $str = shift;
    $str =~ s!/!::!g;
    $str =~ s!^lib::!!;
    $str =~ s!.pm$!!i;
    $str =~ s!^auto::(.+)::.*!$1!;
    return $str;
}

__END__

=encoding utf-8

=head1 NAME

findeps - A command-line tool that resolves dependencies from modules

=head1 SYNOPSIS

just run like below:

 $ findeps your_product.pl | cpanm
 $ findeps Plack.psgi | cpanm
 $ findeps index.cgi | cpanm
 $ findeps t/00_compile.t | cpanm

Now you can run the product you've made with many modules
without installing them every time

=head1 DESCRIPTION

findeps is a simple command line program for ready to run.

L<scandeps.pl> requires you to have L<CPANPLUS>, but this requires just only L<cpanm>.

=head1 DANGER OPTION

    $ findeps  --makeCpanfile Some::Module >| cpanfile

it may be useful when you build a new module with Minilla
but B<NOT recommend>


=head1 LICENSE

Copyright (C) worthmine.

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

=head1 AUTHOR

Yuki Yoshida(L<worthmine|https://github.com/worthmine>)

=cut
