#!/usr/bin/perl

use strict;

use File::Find;
use Getopt::Long;
use Cwd;
use File::Path qw(make_path remove_tree);
use File::Spec;

my $project_root_dir  = getcwd();
my $debug_mod = 0;
my $verbose;
my $story_path;
my $prove_opts = '-v';
my $match_l = $ENV{'match_l'} || 200;
my $host;
my $ini_file_path;

GetOptions (
        "debug=i"       => \$debug_mod,         # numeric
        "match_l=i"     => \$match_l,           # numeric
        "root=s"        => \$project_root_dir,  # string
        "story=s"       => \$story_path,        # string
        "prove=s"       => \$prove_opts,        # string
        "host=s"        => \$host,              # string
        "ini=s"         => \$ini_file_path,     # string


) or die("Error in command line arguments\n");


my $test_root_dir = '/tmp/.outthentic/'.$$;

remove_tree($test_root_dir);
make_path($test_root_dir);

$project_root_dir =  File::Spec->rel2abs($project_root_dir);

my %seen = ();

finddepth(\&wanted_downstreams, $project_root_dir."/modules" );

finddepth(\&wanted_upstreams, $project_root_dir );


sub wanted_upstreams {
    wanted($_,'upstream');
}

sub wanted_downstreams {
    wanted($_,'downstream');
}

sub wanted { 

    my $file = shift;

    my $story_type = shift;

    if ($file eq 'story.check') {

        return if $seen{$File::Find::name};

        my $story_dir = $File::Find::dir;

        my $tfile = $story_type eq 'upstream' ? "$test_root_dir/$story_dir/story.t" : "$test_root_dir/$story_dir/story.d";

        make_path("$test_root_dir/$story_dir");


        open F, ">", $tfile or die $!;
    
        print F "package main;\n\n";
    
        print F "BEGIN { push \@INC, q{$project_root_dir/lib}; }\n";
    
        print F "use strict;\n";

        if ($story_type eq 'upstream'){
            print F "use Test::More q{no_plan};\n";
        }
    
        print F "use Outthentic;\n\n\n";
    
        print F "new_story();\n\n";
    
    
        print F "set_prop( project_root_dir => q{$project_root_dir} );\n";
        print F "set_prop( test_root_dir    => q{$test_root_dir} );\n";
        print F "set_prop( host             => q{$host} );\n";
        print F "set_prop( ini_file_path    => q{$ini_file_path} );\n";
    
        print F "set_prop( story => q{$File::Find::dir} );\n";
        print F "set_prop( story_file => q{$File::Find::dir/story.pl} );\n";
        print F "set_prop( story_check_file => q{$File::Find::dir/story.check} );\n";
        print F "set_prop( story_type => q{$story_type} );\n";
    
        print F "set_prop( debug => $debug_mod );\n";
        print F "set_prop( debug_bytes => 700 );\n";
        print F "set_prop( match_l => $match_l );\n";
    
        if ($story_type eq 'downstream') {
            print F "apply_story_vars();\n";
        }

        if ( -e "$File::Find::dir/story.pm" ){
            print F "do_perl_file('$File::Find::dir/story.pm');\n\n";
        }

        print F "\n\nSKIP: {\n\n";
        print F "\t eval { generate_asserts(q{$File::Find::dir/story.check}) }; die \$@ if \$@;\n\n";
        print F "}\n\n";


        print F 'end_of_story();',"\n\n";

        print F "1;\n\n";    

        close F;

        $seen{$File::Find::name}=1;

   }

}

if ($story_path){
    exec("prove -r $prove_opts   $test_root_dir$project_root_dir/$story_path");
}else{
    exec("prove -r $prove_opts   $test_root_dir$project_root_dir");
}


