# Test file, run like so: "perl 01-App-Relate.t"
#   doom@kzsu.stanford.edu     2007/06/16 02:55:02

use warnings;
use strict;
$|=1;
use Data::Dumper;
my $DEBUG = 0;

use Test::More;
my $total_count;
BEGIN { $total_count = 9;
        plan tests => $total_count };

use Test::Trap qw( trap $trap );
use Test::File::Contents qw( file_contents_identical file_contents_is );

use File::Path qw(mkpath);
use File::Basename;
use File::Copy qw(copy move);
use Data::Dumper;

use FindBin qw($Bin);
use File::Locate::Harder;

BEGIN {
  use_ok( 'App::Relate' );
}

ok(1, "If we made it this far, we're ok. All modules are loaded.");

# skip all tests if there is no locate installation
SKIP:
{
  my $obj;
  my @r = trap {
    $obj = File::Locate::Harder->new();
  };
  if ( my $err_mess = $trap->die ) {
    my $expected_err_mess =
      "File::Locate::Harder is not working. " .
        "Problem with 'locate' installation?";
    $expected_err_mess =~ s{ \s+? }{ \\s+ }gx;

    unless ( $err_mess =~ qr{ $expected_err_mess }x) {
      die "$err_mess";
    }
    my $how_many = $total_count - 2; # all remaining tests
    skip "Problem with installation of 'locate'", $how_many;
  }
  {
    my $test_name = 'Testing creation of a basic App::Relate object';
    my $lfr = App::Relate->new();
    my $type = ref $lfr;
    is($type, 'App::Relate', $test_name);
  }

 # skip all tests if we can't create a locate database
 SKIP:
  { # initialize once for all tests
    my $db_loc = "$Bin/dat/01/locate";
    my $db     = "$db_loc/locate.db";
    my $tree   = "$Bin/dat/01/tree";
    my $loc    = $tree;
    my $stash_loc = "$Bin/dat/01/stash";
    my $stash  = "$stash_loc/filters.yaml";

    ($DEBUG) && print STDERR "stash: $stash\n";

    mkpath( $db_loc ) unless -d $db_loc;
    mkpath( "$stash_loc/expected" ) unless -d "$stash_loc/expected";
    mkpath( "$stash_loc/initial" ) unless -d "$stash_loc/initial";

    my $flh = File::Locate::Harder->new( db => undef );
    my $why = '';
    if ( not(
             $flh->create_database( $tree, $db )
            ) ) {
      $why = "Could not create locate database $db";
    } elsif ( not( $flh->probe_db ) ) {
      $why = "Can't get File::Locate::Harder to work with $db";
    }
    if ($why) {
      my $how_many = $total_count - 3;
      skip $why, $how_many;
    }

    # finally, we may need to skip if search terms clash with the absolute paths
    SKIP:
      {
        my @terms = qw( acoustic_polarization thermo-optic AAA111 );
        my $how_many = 1;
        foreach my $term (@terms) {
          if ($loc =~ m/$term/i) {
            skip "tests invalid because $term matches the path, $loc", $how_many;
            last;
          }
        }

        # given the above search terms, we loop over various other settings
        my @test_cases = (
#
# Disabling test until I understand the failure better:
# Looks like "relate" doesn't create the stash if it doesn't exits (?)
#
#                           {#4
#                            test_name => "Testing relate method",
#                            case_name => "creates yaml file stash",
#                            modifiers => "i",
#                            save_filters_when_used => 0,
#                            method_opts => {
#                                            no_default_filters => 0,
#                                            add_filters        => '',
#                                            regexp             => 0,
#                                           },
#                            expected_matches => [
#                                                 "$tree/AAA111/Acoustic_Polarization/thermo-optic.jpg",
#                                                 "$tree/AAA111/Acoustic_Polarization/thermo-optic.mp3",
#                                                 "$tree/AAA111/Acoustic_Polarization/thermo-optic.txt",
#                                            ],
#                            initial_yaml => undef,
#                            expected_yaml => "$stash_loc/expected/04/filters.yaml",
#                           },
                          {#5
                           test_name => "Testing relate method",
                           case_name => "save_filters_when_used enabled",
                           modifiers => "i",
                           save_filters_when_used => 1,
                           method_opts => {
                                           no_default_filters => 0,
                                           add_filters        => '',
                                           regexp             => 0,
                                          },
                           expected_matches => [
                                                "$tree/AAA111/Acoustic_Polarization/thermo-optic.jpg",
                                                "$tree/AAA111/Acoustic_Polarization/thermo-optic.mp3",
                                                "$tree/AAA111/Acoustic_Polarization/thermo-optic.txt",
                                           ],
                           initial_yaml  => "$stash_loc/initial/05/filters.yaml",
                           expected_yaml => "$stash_loc/expected/05/filters.yaml",
                          },
                          {#6
                           test_name => "Testing relate method",
                           case_name => "save_filters_when_used enabled with ':jpeg' (and no default) ",
                           modifiers => "i",
                           save_filters_when_used => 1,
                           method_opts => {
                                           no_default_filters => 1,
                                           add_filters        => ':jpeg',
                                           regexp             => 0,
                                          },
                           expected_matches => [
                                                "$tree/AAA111/Acoustic_Polarization/thermo-optic.jpg",
                                           ],
                           initial_yaml  => "$stash_loc/initial/06/filters.yaml",
                           expected_yaml => "$stash_loc/expected/06/filters.yaml",
                          },
                          {#7
                           test_name => "Testing relate method",
                           case_name => "save_filters_when_used preserves custom ':skipdull'",
                           modifiers => "i",
                           save_filters_when_used => 1,
                           method_opts => {
                                           no_default_filters => 0,
                                           add_filters        => ':jpeg',
                                           regexp             => 0,
                                          },
                           expected_matches => [
                                                "$tree/AAA111/Acoustic_Polarization/thermo-optic.jpg",
                                           ],
                           initial_yaml  => "$stash_loc/initial/07/filters.yaml",
                           expected_yaml => "$stash_loc/expected/07/filters.yaml",
                          },



                       );

        foreach my $test_case ( @test_cases ) {
          my $modifiers              = $test_case->{ modifiers };
          my $test_name              = $test_case->{ test_name };
          my $case_name              = $test_case->{ case_name };
          my $save_filters_when_used = $test_case->{ save_filters_when_used };
          my $method_opts            = $test_case->{ method_opts };
          my $expected_matches       = $test_case->{ expected_matches };
          my $expected_yaml          = $test_case->{ expected_yaml };
          my $initial_yaml           = $test_case->{ initial_yaml };

          if ($DEBUG) {
            print STDERR "expected_yaml: \n$expected_yaml\n";
            print STDERR "initial_yaml: \n$initial_yaml\n" if $initial_yaml;
            print STDERR "expected_yaml is there\n" if -e $expected_yaml;
            print STDERR "initial_yaml is there\n"  if ($initial_yaml && -e $initial_yaml);
            print STDERR "stash is there\n" if -e $stash;
          }

          # set up the yaml file stash to a known state
          if ( $initial_yaml ) {
            copy( $initial_yaml, $stash);
          } elsif ( not( defined( $initial_yaml ) ) ) {
            # If 'initial_yaml' is undef we don't want one to start with
            unlink( $stash ) if -e $stash;
          };


          my $lfr = App::Relate->new(
                                                   { storage                => $stash,
                                                     locatedb              => $db,
                                                     modifiers              => $modifiers,
                                                     save_filters_when_used => $save_filters_when_used,
                                                   } );
          $lfr->debugging(1) if $DEBUG;

          my $matches = $lfr->relate( \@terms, $method_opts );

          ($DEBUG) && print STDERR "matches: ". Dumper($matches) . "\n";

          my $expected_matches_sorted = [ sort( @{ $expected_matches } ) ];
          my $matches_sorted =          [ sort( @{ $matches } ) ];
          is_deeply( $matches_sorted, $expected_matches_sorted,
                      "$test_name $case_name: matches match");
          file_contents_identical( $stash, $expected_yaml,
                      "$test_name $case_name: yaml output");

        }
      } # end skip -- $term matches path
  } # end skip -- can't create locate db
} # end skip -- problem with installation of locate
