#!/usr/bin/perl
use strict;
use warnings;

use File::Find;
use File::Path qw(make_path);
use Cwd q{abs_path};
use File::Slurp;
use Getopt::Std;

=head1 DESCRIPTION

fennec_scaffold will attempt to build out a quick set of tests for all .pm's in a given lib dir.

=head1 USEAGE

  fennec_scaffold -l ./lib -v

=head2 OPTS 

=over

=item * B<-l> : lib dir (defaults to ./lib)

=item * B<-t> : test dir (defaults to ./t)

=item * B<-T> : test package prefix (defaults to TEST);

=item * B<-v> : verbose, extra with -vv

=item * B<-o> : overwrite existing files

=item * B<-x> : dry run, do not write tests

=back

=cut

our %opts;
getopt('vxol:t:T:', \%opts);

our %MODULES;

our $lib_dir  = abs_path( $opts{l} || $ENV{FENNEC_LIB_DIR} || './lib' );
$lib_dir      =~ s{/$}{}; # if lib has a trailing slash, remove it for sanity

our $test_dir = abs_path( $opts{t} || $ENV{FENNEC_TEST_DIR} || './t' );
$test_dir     =~ s{/$}{}; # if test has a trailing slash, remove it for sanity

our $test_pkg = $opts{T} || $ENV{FENNEC_TEST_PREFIX} || 'TEST';
$test_pkg =~ s{:*$}{}; # if pkg ends in '::' remove it for sanity

my $WRITTEN_TESTS ;

find({ wanted => sub { $WRITTEN_TESTS += write_test( $File::Find::name, $File::Find::dir ); },
       follow => 1,
     } ,
     $lib_dir
    );

printf qq{%s %d TESTS\n\n}, (exists $opts{x}) ? 'WOULD HAVE WRITTEN' : 'WROTE',  $WRITTEN_TESTS;

#---------------------------------------------------------------------------
#  
#---------------------------------------------------------------------------
sub write_test {
   my ($file, $dir) = @_;

   return 0 unless $file =~ m/\.pm$/;

   printf qq{ FOUND: %s \n}, $file
      if exists $opts{v} && $opts{v} eq 'v';

   my ($test_file,$test_dir) = map{ s/\Q$lib_dir\E/$test_dir/; $_} $file, $dir;

   return 0 if -e $test_file && ! exists( $opts{o} ); # DON'T OVERWRITE unless asked to
   make_path( $test_dir );

   my $test_package = join '::', $test_pkg, file_to_package($test_file);
   my $org_package  = file_to_package($file);

   unless ( exists $opts{x} ) {
      my $content = <<EOT;
package $test_package;
use strict;
use warnings;
use Fennec;

tests load {
   require_ok( '$org_package' );
}

1;
EOT
      write_file( $test_file,
                  { no_clobber => exists( $opts{o} ) ? 0 : 1,
                    atomic     => 1,
                  },
                  $content,
                );
   }
   printf qq{ WROTE: %s at %s\n}, $test_package, $test_file
      if exists $opts{v};

   return 1;
}

sub file_to_package {
    my ( $file ) = @_;
    my $out = $file;
    $out =~ s|^.*\Q$test_dir\E/||g;
    $out =~ s|\.pm$||g;
    $out =~ s|/+|::|g;
    return $out;
}

=head1 MANUAL

=over 2

=item L<Fennec::Manual::Quickstart>

The quick guide to using Fennec.

=item L<Fennec::Manual::User>

The extended guide to using Fennec.

=item L<Fennec::Manual::Developer>

The guide to developing and extending Fennec.

=item L<Fennec::Manual>

Documentation guide.

=back

=head1 AUTHORS

Chad Granum L<exodist7@gmail.com>

=head1 COPYRIGHT

Copyright (C) 2010 Chad Granum

Fennec is free software; Standard perl licence.

Fennec is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the license for more details.
