#!/usr/bin/perl -w

#use strict;
use App::Rad;
use Cwd qw(getcwd);
use SweetPea;
use SweetPea::Application::Devel;

BEGIN {
  eval "use SweetPea::Application 0.001 ();";
  if ($@) {
    die print <<END;
  Please install SweetPea::Application (web application framework)
  which is being reported as missing or broken. You may install via CPAN
  or CPANPLUS using one of the following commands.
  
    cpan SweetPea::Application
    perl -MCPAN -e shell
    
END
  }
}

my $application_root = getcwd;
my $development_root = $0;
   $development_root =~ s/(.*[\\\/])[^\\\/]+$/$1/;

my $devel = SweetPea::Application::Devel->new;

my $usage = {
  'make' => q/
make - build application structure with boiler-plate code
    
Usage:
    sweetpea-app make [--argument, ]
    e.g. sweetpea-app make --stack
    
Argument(s):
    script - makes a sweetpea script without application structure (minimal)
    basic  - makes a sweetpea application with basic MVC structure (moderate)
    stack  - makes a sweetpea full-stack application w\/structure  (complete)
/,
  'data' => q/
data - create a database with application support
    
Usage:
    sweetpea-app data [--argument, ] --dsn=dbi:???? --user=???? --pass=????
    e.g. sweetpea-app data --create --dsn=dbi:mysql:foo --user=root --pass
    
Argument(s):
    create - creates a database with sweetpea application support
    update - update database configuration files from database
/,
  'model' => q/
model - create a model with boiler-plate code
    
Usage:
    sweetpea-app model [--argument, ]
    e.g. sweetpea-app model --name=user\/profile
    creates User\/Profile.pm in the Models folder
    
Argument(s):
    name - defines the name and placement of the Model class
/,
  'view' => q/
view - create a view with boiler-plate code
    
Usage:
    sweetpea-app view [--argument, ]
    e.g. sweetpea-app view --name=email\/plain
    creates Email\/Plain.pm in the Views folder
    
Argument(s):
    name - defines the name and placement of the View class
/,
  'ctrl' => q/
ctrl - create a controller with boiler-plate code
    
Usage:
    sweetpea-app ctrl [--argument, ]
    e.g. sweetpea-app ctrl --name=catalog\/products
    creates Catalog\/Products.pm in the Controllers folder
    
Argument(s):
    name - defines the name and placement of the Controller class
/,
  'yaml' => q/
yaml - create a yaml profile for validating input and generating html
    
Usage:
    sweetpea-app yaml [--argument, ]
    e.g. sweetpea-app yaml --name=registration
    creates registration.yml in the configuration folder
    
Argument(s):
    name - defines the name and placement of the yaml document
/,
};

sub make {
  my $c = shift;
  if ($c->options->{script}) {
    $devel->make_file(
      'file'    => ".htaccess",
      'content' => $devel->process_template(
        'htaccess-template.tt',
        {}
      ),
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => ".pl",
      'content' => $devel->process_template(
        'scriptonly-template.tt',
        {
          shebang => $^X,
          version => $SweetPea::VERSION
        }
      ),
      'bitmask' => 0644
    );
  }
  elsif ($c->options->{basic}) {
    $devel->make_file(
      'file'    => ".htaccess",
      'content' => $devel->process_template(
        'htaccess-template.tt',
        {}
      ),
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => ".pl",
      'content' => $devel->process_template(
        'dispatcher-template.tt',
        {
          shebang => $^X,
          version => $SweetPea::VERSION
        }
      ),
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "sweet/application/Controller/Root.pm",
      'content' => $devel->process_template(
        'controller-root-template.tt',
        {}
      ),
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "sweet/application/Controller/Sweet.pm",
      'content' => $devel->process_template(
        'controller-sweet-template.tt',
        {}
      ),
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "sweet/application/Model/Schema.pm",
      'content' => $devel->process_template(
        'model-schema-template.tt',
        {}
      ),
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "sweet/application/View/Main.pm",
      'content' => $devel->process_template(
        'view-main-template.tt',
        {}
      ),
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "sweet/App.pm",
      'content' => $devel->process_template(
        'app-template.tt',
        {}
      ),
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "sweet/sessions/empty",
      'content' => 'placeholder',
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "sweet/templates/empty",
      'content' => 'placeholder',
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "static/empty",
      'content' => 'placeholder',
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "extras/Makefile.PL",
      'content' => $devel->process_template(
        'makefile-template.tt',
        {}
      ),
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "extras/TODO",
      'content' => 'placeholder',
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "extras/Changes",
      'content' => 'placeholder',
      'bitmask' => 0644
    );
  }
  elsif ($c->options->{stack}) {
    $devel->make_file(
      'file'    => ".htaccess",
      'content' => $devel->process_template(
        'htaccess-template.tt',
        {}
      ),
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => ".pl",
      'content' => $devel->process_template(
        'app-dispatcher-template.tt',
        {
          shebang => $^X,
          version => $SweetPea::Application::VERSION
        }
      ),
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "sweet/application/Controller/Root.pm",
      'content' => $devel->process_template(
        'controller-root-template.tt',
        {}
      ),
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "sweet/application/Controller/Sweet.pm",
      'content' => $devel->process_template(
        'app-controller-sweet-template.tt',
        {}
      ),
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "sweet/application/Model/Schema.pm",
      'content' => $devel->process_template(
        'model-schema-template.tt',
        {}
      ),
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "sweet/application/View/Main.pm",
      'content' => $devel->process_template(
        'view-main-template.tt',
        {}
      ),
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "sweet/App.pm",
      'content' => $devel->process_template(
        'app-template.tt',
        {}
      ),
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "sweet/sessions/empty",
      'content' => 'placeholder',
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "static/empty",
      'content' => 'placeholder',
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "sweet/configuration/datastores/development/empty",
      'content' => 'placeholder',
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "sweet/configuration/datastores/production/empty",
      'content' => 'placeholder',
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "sweet/configuration/application.yml",
      'content' => $devel->process_template(
        'application-yml-template.tt',
        {
          head => '---'
        }
      ),
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "sweet/configuration/datastores.yml",
      'content' => $devel->process_template(
        'datastores-yml-template.tt',
        {
          head => '---'
        }
      ),
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "sweet/configuration/permissions.yml",
      'content' => $devel->process_template(
        'permissions-yml-template.tt',
        {
          head => '---'
        }
      ),
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "sweet/locales/en.yml",
      'content' => $devel->process_template(
        'translation-en.tt',
        {
          head => '---'
        }
      ),
      'bitmask' => 0644
    );    
    $devel->make_file(
      'file'    => "sweet/templates/elements/form.tt",
      'content' => $devel->file_content(
        'element-form-template.tt'
      ),
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "sweet/templates/elements/grid.tt",
      'content' => $devel->file_content(
        'element-grid-template.tt'
      ),
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "sweet/templates/layouts/default.tt",
      'content' => qq(
<!doctype html>
<head><title>Welcome to the SweetPea Web Framework</title></head>
<body>
    <h2>Thanks for trying the SweetPea-Application Web Framework!</h2>
    SweetPea::Application is a full stack web application framework
    utilizing conventional wisdom and granular configuration over a highly
    sophisticated Push MVC architecture.<br/>
    [% content %]
</body>
</html>
      ),
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "sweet/templates/index.tt",
      'content' => 'Now go be fruitful and multiply.',
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "extras/t/00-load.t",
      'content' => $devel->process_template(
        'test-starter-template.tt',
        {}
      ),
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "extras/Makefile.PL",
      'content' => $devel->process_template(
        'makefile-template.tt',
        {}
      ),
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "extras/TODO",
      'content' => 'placeholder',
      'bitmask' => 0644
    );
    $devel->make_file(
      'file'    => "extras/Changes",
      'content' => 'placeholder',
      'bitmask' => 0644
    );
  }
  else {
    return $usage->{make};
  }
  return q/
SweetPea application files were created successfully.

Attention *nix users, you may need to fix permissions for generated files.
If needed run:

sudo chown -R www-data *
sudo chmod -R 0644 *
  /;
}

sub data {
  my $c = shift;
  if (($c->options->{create} || $c->options->{update})
      && $c->options->{dsn}
      && $c->options->{user}) {
    my @dsn = (
      $c->options->{dsn},
      $c->options->{user}
    );
    push (@dsn, $c->options->{pass}) if $c->options->{pass};
    if ($c->options->{create}) {
        $devel->create_database(@dsn);
    }
    if ($c->options->{update}) {
        $devel->update_database(@dsn);
    }
  }
  else {
    return $usage->{data};
  }
  return q/
SweetPea database successfully configured for application usage.

Note, if after you add additional tables to your database, you will need to
update your configuration files which are stored under sweet\/configuration.
When ready run the following command to update them automatically:

sweetpea-app data --update [--arguments, ]
sudo chmod -R 0644 *
/;
}

sub model {
  my $c = shift;
  if ($c->options->{name}) {
    my $model = $c->options->{name};
      $model =~ s/\.pm$//;
      $model =~ s/\\/\//g;
    my $package_name = $model;
      $package_name = join("::", map {ucfirst $_} split(/[\/\\]/, $package_name));
    $devel->make_file(
      'file'    => "sweet/application/Model/$model.pm",
      'content' => $devel->process_template(
        'new-model-template.tt',
        {
          'package' => $package_name
        }
      ),
      'bitmask' => 0644
    );
      return qq/
SweetPea has successfully create model $package_name under folder
sweet\/application\/Model.
sudo chmod -R 0644 *
/;
  }
  else {
    return $usage->{model};
  }
}

sub view {
  my $c = shift;
  if ($c->options->{name}) {
    my $view = $c->options->{name};
      $view =~ s/\.pm$//;
      $view =~ s/\\/\//g;
    my $package_name = $view;
      $package_name = join("::", map {ucfirst $_} split(/[\/\\]/, $package_name));
    $devel->make_file(
      'file'    => "sweet/application/View/$view.pm",
      'content' => $devel->process_template(
        'new-view-template.tt',
        {
          'package' => $package_name
        }
      ),
      'bitmask' => 0644
    );
      return qq/
SweetPea has successfully create view $package_name under folder
sweet\/application\/View.
sudo chmod -R 0644 *
/;
  }
  else {
    return $usage->{view};
  }
}

sub ctrl {
  my $c = shift;
  if ($c->options->{name}) {
    my $controller = $c->options->{name};
      $controller =~ s/\.pm$//;
      $controller =~ s/\\/\//g;
    my $package_name = $controller;
      $package_name = join("::", map {ucfirst $_} split(/[\/\\]/, $package_name));
    $devel->make_file(
      'file'    => "sweet/application/Controller/$controller.pm",
      'content' => $devel->process_template(
        'new-controller-template.tt',
        {
          'package' => $package_name
        }
      ),
      'bitmask' => 0644
    );
      return qq/
SweetPea has successfully create controller $package_name under folder
sweet\/application\/Controller.
sudo chmod -R 0644 *
/;
  }
  else {
    return $usage->{ctrl};
  }
}

sub yaml {
  my $c = shift;
  if ($c->options->{name}) {
    my $file = $c->options->{name};
      $file =~ s/\.y\w?ml$//;
      $file =~ s/\\/\//g;
    $devel->make_file(
      'file'    => "sweet/configuration/datastores/development/$file.yml",
      'content' => $devel->process_template(
        'new-profile-yml.tt',
        {}
      ),
      'bitmask' => 0644
    );
      return qq/
SweetPea has successfully create controller $file.yml under folder
sweet\/application\/configuration\/datastores\/development and
sweet\/application\/configuration\/datastores\/production.
sudo chmod -R 0644 *
/;
  }
  else {
    return $usage->{yaml};
  }
}

sub help {
  my $c = shift;
  my $u =
  q/
Usage: sweetpea-app command [arguments]

Available Commands:
    
    help        show syntax and available commands
    
    make        build application boiler-plate code
    data        create and maintain the database
    
    model       create a boiler-plate model
    view        create a boiler-plate view
    ctrl        create a boiler-plate controller
    
    yaml        create a yaml document for validation, etc
    
* For help, use sweetpea-app help --cmd=[command]
/;
  
  if ($c->options->{cmd} && $usage->{$c->options->{cmd}}) {
    return $usage->{$c->options->{cmd}};
  }
  else {
    return $u;
  }
}

App::Rad->run;

__END__

=head1 NAME

SweetPea-App - RAD Utility for SweetPea::Application

=head1 SYNOPSIS

sweetpea-app [options] [params]

 Options:
   see sweetpea-app help

=head1 DESCRIPTION

B<sweetpea-app> is used to generate the initial application structure and
any additional Models, Views, and/or Controllers you may need.

* For POD documentation on the SweetPea module, try perldoc SweetPea.pm

=cut