#!/usr/bin/perl -w
use strict;
use warnings;
use TIE::Slurp;
use Text::Wrap;
$Text::Wrap::columns=72;
use Getopt::Long;
my $VERSION = 0.3;


=pod

=head1 NAME

build_enzyme_app

=head1 SYNOPSIS

build_enzyme_app --appname [Application name]  --dbfile [relative path to database file --tables [comma delimited list of tables]


=head1 SUMMARY

Script to produce a L<Catalyst> CRUD (Create, Retrieve, Update, Delete)
web application using L<Catalyst::Enzyme>.  Use the script as above and follow the instructions in it's output.

=h1 PREREQUISITES

TIE::Slurp Text::Wrap Getopt::Long; Catalyst Catalyst::Enzyme

=pod README

A script to generate a Maypole-like application with Catalyst and
Catalyst::Enzyme.

=pod SCRIPT CATEGORIES

Web

=head1 TODO

Do some automatic authentication stuff if there is a "user" table.

Add a default search function for each table

Make a splash page e.g. /frontpage rather than going straight to a table.

=cut

my ($appname, @tables, $dbfile, $help);

GetOptions ("appname=s" => \$appname,
            "dbfile=s" => \$dbfile,
            "tables=s" => \@tables,
            "help" => \$help,
           );
@tables = split(/,/,join(',',@tables));

$dbfile = $ENV{PWD} ."/$dbfile";
if ($help || !($appname && $dbfile && @tables)) {
  warn "usage:  build_enzyme_app --appname [Application name] --dbfile [relative path to database file --tables [comma delimited list of tables]\n";
  exit;
}

my $script_prefix = lc($appname);
my $start_dir = $ENV{PWD};
my $model_class_file;
my $dbname;
my $model_class;

    warn "Creating Catalyst Application\n";
    system "catalyst.pl $appname";
    chdir $appname;
    #system "prove -Ilib t";
    my $core;
    tie $core, 'Tie::Slurp' => "lib/$appname.pm" or warn "Can't find $appname.pm";
    warn "Updating use Catalyst declaration in $appname/lib/$appname.pm\n";
    $core =~ s/use Catalyst qw\/-Debug Static::Simple\/;/use Catalyst qw!-Debug Static::Simple DefaultEnd FormValidator!;/s;
    warn "Altering some of the comments in $appname/lib/$appname.pm\n";
    $core =~ s/Hello World/Default table to send to/s;
    $core =~ s/Output a friendly welcome message/Setup the default action/s;
# $tables[0] is the table we'll send to the front page for now
    # splash page to come later
    warn "Altering default action in $appname/lib/$appname.pm\n";
    $core =~ s/\$c->response->body\( \$c->welcome_message \)/\$c->res->redirect("\/$tables[0]")/s;
    my $test1;
    tie $test1, 'Tie::Slurp' => "t/01app.t" or warn "unable to open t/01app.t";
    warn "Updating $appname/t/01app.t to reflect new default action\n";
    $test1 =~ s/ok\( request\('\/'\)->is_success \)/ok\(request\("\/"\)->is_redirect, "Redirect ok"\)/s;

    warn "Creating view with Enzyme::TT\n";
    my $view_cmd = "script/".$script_prefix."_create.pl view TT Enzyme::TT";
    system $view_cmd;

    warn "Creating the database using SQLite and dbish";
    mkdir "db" or die "unable to make directory $ENV{PWD}/db";
    system "dbish dbi:SQLite:dbname=db/$script_prefix.db < $dbfile";
    $dbname = "db/$script_prefix.db";


    print wrap ('','',"\nWARNING\nMy version of sqlite returns an error at this point, even
though the test Catalyst::Enzyme database loads ok.  It's up to you to
check that loading the database worked.  I'm going to let you check
that everything went ok right now.  Press return to continue when
you're done.  Press control-Z to go back to the shell and fg then
return to continue.");

#    my $tmp = <STDIN>;

  foreach my $class_bits (@tables) {
    # make CDBI::Loader compatible class names
    my @class_bits = split '_', $class_bits;
      foreach (@class_bits) { s/(.*)/\u$1/ }
      $model_class = join "", @class_bits;
    warn "Creating Class DBI model for database:  db/$script_prefix.db\n";
    system "script/".$script_prefix."_create.pl model ".$appname."DB Enzyme::CDBI dbi:SQLite:dbname=$dbname";
    $model_class_file = "lib/$appname/Model/$appname"."DB/$model_class.pm";
  
    warn "Creating CRUD controller for $model_class\n";
    system "script/".$script_prefix."_create.pl controller $model_class Enzyme::CRUD ".$appname."DB::$model_class";
  }

   warn wrap ("","","\nWe're making the assumptions about the stringified name you want for each one-to-many database relationship here.  Modify the __PACKAGE__ declarations in  lib/$appname/Model/$appname/"."DB yourself if you want different.\n");
 my $newdir = "lib/$appname/Model/$appname"."DB";
     chdir $newdir or die "Unable to chdir to $newdir";
     opendir(DIR,".") or die "can't open $ENV{PWD}/.";
     my @model_classes = grep {/\.pm$/ && -f $_} readdir(DIR);
     foreach (@model_classes) {
       warn "Modifying $_\n";
       my $code;
       tie $code, 'Tie::Slurp' => $_  or die "unable to open $_";
       $code =~ s/#__/__/sg;
     }
    # $appname/lib/Model/$appnameDB/*pm

# Create nice header for each page.

my $header_template;
my $header_file = "$start_dir/$appname/root/base/header.tt";
tie $header_template, 'Tie::Slurp' => $header_file  or die "unable to open $_";
my $html ='|';
foreach (@tables) {
  $html = $html . "<a href=\"/$_\">$_<\/a> |\n"
}

$header_template =~ s/(.*<div class="content">)(.*)/$1 $html $2/s;

  warn "\n\n";
  warn wrap ("\t",'',"OK, that's about all we can usefully do for you.  Now you have to read the rest of the Catalyst::Enzyme docs and configure your application to be useful.  Remember that the Class::DBI::Loader module you used as a part of this setup process knows a bit about how to set up table relationships from your database schema, so it might be a good idea to specify these in the SQL used to set up the database.\n");
  warn wrap ("\t",'',"\nThis script will now exit, and you will be able to test it by changing directory to $appname and running the command \"script/$script_prefix"."_server.pl\" and following the instructions from there\n\n");


#system "script/$script_prefix"."_server.pl";

