use strict;
use warnings;
use Test::Tester;
use Test::More 0.88;
use Test::Needs;

use Dist::Zilla::Tester;
use Path::Tiny;
use Cwd ();

BEGIN {
  plan skip_all => 'Perl must be in your path for these tests'
    unless qx/perl -e "print 123"/ == 123;

  if ( $^O eq 'MSWin32' ) {
    test_needs { 'Test::Spelling' => 0.17 };
  }
}

# This test uses a custom "spell checker" defined in corpus/*/dist.ini
# (setting it here didn't work, it seems to get overridden in the do-file)
# to produce reliable output so that we can ensure that each expected
# file (beneath bin/ and lib/) is in fact being tested.
# (We wouldn't want to generate a script that didn't actually check our files).
# Defining a custom one enables us to get reliable results regardless
# of which version of which spell checker (or none at all) is available.

# This test builds the fake dists (in corpus/) with dzil,
# then executes the actual test script generated by this module.
# Test::Tester intercepts the Test::Builder calls to allow us to verify
# which tests have been run (for example 'spelling ok for lib/Foo.pm').

# lib/ and bin/
# (bin/foo should be 'not ok' because of a spelling error)
spell_check_dist( foo   => [ path('bin/foo') => {ok => 0}], path('lib/Foo.pm') );

# just lib/
spell_check_dist( nobin => path('lib/Foo.pm') );

done_testing;

# @files should be a file (name) or an array ref of [file, hash-to-override-expected-results]
sub spell_check_dist {
  my ($dir, @files) = @_;

  # NOTE: windows started throwing stupid permission-denied errors
  # during File::Temp's tempdir CLEANUP for the xt test that dzil writes
  # but I have absolutely no idea why and I wasn't able to come up with
  # a workaround or any useful diagnostics other than the fact that the issue
  # only occurs within this original process.  As soon as the test is done the file
  # and directories can be removed using the same (perl) methods.
  # The tests still count as 'passing' however,
  # and the dir will likely get cleaned up later, so :-P

  my $tzil = Dist::Zilla::Tester->from_config({
    dist_root => path('corpus', $dir),
  }, {
    tempdir_root => '.build', # avoid creating ./tmp
  });
  $tzil->build;

  my $cwd = Cwd::cwd;
  # tests typically run from the build dir
  my $build_dir = path($tzil->tempdir)->child('build');
  chdir $build_dir or die "chdir failed: $!";

  check_tests(
    sub {
      # all_pod_files_spelling_ok sets a plan which causes problems
      local *Test::Tester::Delegate::plan = sub {};

      # run the actual xt file generated by this module
      do "${\ path(qw(xt author pod-spell.t)) }";
    },
    [
      # results we're expecting
      map {
        +{
          # expected test result ('ok' or 'not ok')
          ok => 1,
          # file name
          name => 'POD spelling for ' . $_->[0],
          # ignore depth/Level tests, we just want to know that the file was checked
          depth => undef,
          # overridden expectations (in args to spell_check_dist)
          %{ $_->[1] },
        },
      }
      map { ref $_ eq 'ARRAY' ? $_ : [$_ => {}] }
        @files
    ],
    "spell check pod for $dir"
  );

  # change back
  chdir $cwd or die "chdir failed: $!";
}
