#!/usr/bin/env perl
########################################################################
# housekeeping
########################################################################

BEGIN
{
    $\  = "\n";

    print STDERR "Execute: '$0'.";
}

use 5.6.0;
use strict;

use version;

use Test::More;

use Cwd                 qw( getcwd          );
use FindBin             qw( $Bin            );
use File::Basename      qw( dirname         );
use File::Find          qw( finddepth       );
use List::Util          qw( pairmap uniq    );
use List::MoreUtils     qw( zip             );

use File::Spec::Functions
qw
(
    &catpath
    &catdir
);

use FindBin qw( $Bin );
use lib "$Bin/../lib";
use Test::KwikHaks;

########################################################################
# package variables
########################################################################

$\    = "\n";

my $verbose     = $ENV{ VERBOSE_FROMPERLVER };

my $v_base  = 'version';

my $md  = Test::KwikHaks->can( 'mkdir_if' )
or die "Botched Test::KwikHaks: cannot 'mkdir_if'.\n";

my @v_stringz
= do
{
    my @versionz 
    = qw
    (
        5.0.1
        5.6.0
        5.8.8
        5.888.888
        5.999.999
    );

    my @formatz
    = qw
    (
        %d.%d.%d
        %d.%03d%03d
        %d.%03d.%03d
        %d.%03d_%03d
    );

    # lexical sort works.

    uniq
    sort
    map
    {
        (
            $_, "v$_"
        )
    }
    pairmap
    {
        sprintf $a => @$b
    }
    map
    {
        my @v   = ( [ split /\W/ ] ) x @formatz;

        zip @formatz, @v
    }
    @versionz;
};

my @mod_specz = 
(
    [ qw( Foo   use ) ],
    [ qw( Bar   no  ) ],
);

my @file_specz =
(
    [
        qw( lib pm ),
        <<'END',
package %s;
our VERSION='1.234567';
%s %s;
1
__END__
END
    ],
    [
        qw( pod pod ),
        <<'END',
=head NAME

%s - Module for testing %s %s
END
    ],
    [
        # easier to parse use for validatio of
        # the module parser.

        qw( etc dat ),
        <<'END',
%s %s;
END
    ],
);

########################################################################
# utility subs
########################################################################

sub open_path
{
    my $path    = catpath '' => @_;

    open my $fh, '>', $path
    or 
    die "Failed open: '$path', $!\n";

    $fh
}

sub make_v_file
{
    my ( $ver, $dir, $base, $name, $use, $format ) = @_;

    my $fh  = open_path $dir => $base;

    # normally disk-full issues won't show up until 
    # the close can't flush the buffer; need to check 
    # both.
    #
    # note: lack of separator between $fh & $mod_fmt.

    my $text    = sprintf $format => $name, $use, $ver;

    print $fh $text
    or die "Failed print: '$base', $!n";

    close $fh
    or die "Failed close: '$base', $!\n";
}

########################################################################
# generate a directory for each version with Foo.pm using the
# version and Bar.pm having "no" version, etc/version.dat having
# the version for comparision.

$DB::single = 1;

# i.e., start in ./t

my $work_d  = dirname $Bin;

chdir $work_d
or die "Failed chdir: $!.\n";

print STDERR 'Working directory: ' . getcwd;

$work_d     = $md->( $work_d, $v_base )
or die "Failed mkdir: '$v_base', $!.\n";

chdir $work_d
or die "Failed chdir: '$work_d', $!";

for my $v_string ( @v_stringz )
{
    eval
    {
        my $vers_d  = $md->( "./$v_string" );

        print "Version dir: '$vers_d'"
        if $verbose;

        for( @file_specz )
        {
            my ( $sub, $ext, $format ) = @$_;

            my $v_sub   = $md->( $vers_d, $sub );

            print "Subdir: '$v_sub'"
            if $verbose;

            for( @mod_specz )
            {
                my( $name, $use ) = @$_;

                my $base    = "$name.$ext";

                print "Generate: '$base'"
                if $verbose;

                make_v_file $v_string, $v_sub, $base, $name, $use, $format;
            }
        }

        1
    }
    or warn;
}

done_testing;

# this is not a module
0
__END__
