#!/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  = $ENV{'OUTTHENTIC_ROOT'} || getcwd();
my $silent_mod = 0;
my $debug_mod = 0;
my $story_path;
my $match_l = $ENV{'match_l'} || 200;
my $ini_file_path;
my $yaml_file_path;
my $json_file_path;
my @runtime_params;


GetOptions (

        "silent"        => \$silent_mod,        # boolean
        "debug=i"       => \$debug_mod,         # numeric
        "match_l=i"     => \$match_l,           # numeric
        "root=s"        => \$project_root_dir,  # string
        "story=s"       => \$story_path,        # string
        "ini=s"         => \$ini_file_path,     # string
        "yaml=s"        => \$yaml_file_path,    # string
        "json=s"        => \$json_file_path,    # string
        "param=s"       => \@runtime_params,    # string


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


my $test_root_dir = $ENV{SPARROW_ROOT} ? "$ENV{SPARROW_ROOT}/tmp/".$$ : '/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;

        make_path("$test_root_dir/$story_dir");

        my $tfile = "$test_root_dir/$story_dir/sparrow.pl";

        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";

        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( ini_file_path    => q{$ini_file_path} );\n"    if $ini_file_path;
        print F "set_prop( yaml_file_path   => q{$yaml_file_path} );\n"  if $yaml_file_path;
        print F "set_prop( json_file_path   => q{$json_file_path} );\n"  if $json_file_path;
    
        print F "set_prop( story => q{$File::Find::dir} );\n";
        print F "set_prop( story_dir => q{$File::Find::dir} );\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";
        if ($silent_mod){
          print F "set_prop( verbose => 0 );\n";
        }else{
          print F "set_prop( verbose => 1 );\n";
        }
        print F "set_prop( debug => $debug_mod );\n";
        print F "set_prop( match_l => $match_l );\n";
        print F "set_prop( runtime_params => q{".(join ':::', @runtime_params)."} );\n";

        print F "\nset_story();\n\n";
        print F "\npopulate_config();\n\n";
    
        if ($story_type eq 'downstream') {
            print F "apply_story_vars();\n";
        }

        if ( -e "$File::Find::dir/story.pm" ){
            print F "do_perl_hook('$File::Find::dir/story.pm');\n\n";
        }elsif ( -e "$File::Find::dir/hook.pl" ){
            print F "do_perl_hook('$File::Find::dir/hook.pl');\n\n";
        }elsif ( -e "$File::Find::dir/hook.rb" ){
            print F "do_ruby_hook('$File::Find::dir/hook.rb');\n\n";
        }elsif ( -e "$File::Find::dir/hook.bash" ){
            print F "do_bash_hook('$File::Find::dir/hook.bash');\n\n";
        }

        print F "eval \n\n{ generate_asserts(q{$File::Find::dir/story.check}) };\n\n die \$@ if \$@;\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("perl $test_root_dir$project_root_dir/$story_path/sparrow.pl");
}else{
    exec("perl $test_root_dir$project_root_dir/sparrow.pl");
}


