# ----------  perl
# This file intentionally left w/o execute permission. Intended to be called
# manually via 'perl' command to make sure it is the same interpreter/env as
# the one used to run the app, which may not be the system perl.
#
# From the app root:
#
#    perl devel/regen_schema.pl
#
# ----------

use strict;
use warnings;

use DBIx::Class::Schema::Loader;
use Module::Runtime;
use IPC::Cmd qw[can_run run_forked];
use Path::Class qw(file dir);

my $Go = $ARGV[0] && $ARGV[0] eq '--go';

use FindBin;
use lib "$FindBin::Bin/../lib";

my $app_class   = '[%- name -%]';
my $model_class = '[%- model_class -%]';

my $approot = "$FindBin::Bin/..";
my $applib = "$approot/lib";

# make an $INC{ $key } style string from the class name
(my $pm = "$app_class.pm") =~ s{::}{/}g;
my $appfile = file($applib,$pm)->absolute->resolve;

# This is purely for Catalyst::Utils::home() which will be invoked when 
# we require the model class in the next statement so it can find the
# home directory w/o having to actually use/load the app class:
$INC{ $pm } = "$appfile";

Module::Runtime::require_module($model_class);

my ($schema_class,$dsn,$user,$pass) = (
  $model_class->config->{schema_class}, 
  $model_class->config->{connect_info}{dsn},
  $model_class->config->{connect_info}{user}, 
  $model_class->config->{connect_info}{password}
);

[% IF from_ddl %]
{ # from_ddl logic

  my $sqlite3 = can_run('sqlite3') or die 'FATAL: sqlite3 command not available!';
  my $ddl = file($approot,'[%- from_ddl -%]')->resolve;

  my ($dbi,$driver,$db_path) = split(/\:/,$dsn,3);
  die "malformed dsn '$dsn' - expected it to start with 'dbi:'" unless ($dbi eq 'dbi');
  die join('',
    "cannot use dbi driver '$driver' when generating from DDL",
    " - only 'SQLite' is supported"
  ) unless ($driver eq 'SQLite');
  
  # Here we are parsing the sqlite db path in one of two ways, both specific to
  # the way the RapidApp bootstrap process generated the model class. The first
  # way is to look for the special method _sqlt_db_path which is generated by
  # ForRapidDbic during bootstrap, and the second is to attempt to parse directly
  # from the dsn, which relies on the 3rd argument being the path (which isn't the
  # only possible config, which is why _sqlt_db_path was added, in case the user
  # needs to change the dsn, add an option, etc)
  my $sqlt = file( $model_class->can('_sqlt_db_path') 
    ? $model_class->_sqlt_db_path() 
    : $db_path
  );
  
  print join("\n",'',
    "Regenerating SQLite database from DDL - EXISTING DATA WILL BE DESTROYED!",'',
    "  Source DDL : $ddl",
    "  Target DB  : $sqlt",''
  );
  
  if($Go) {
    print "\nCalled with --go - proceeding without confirmation...\n";
  }
  else {
    print join("\n",'',
      "Type in 'go' and hit ENTER to proceed, anything else to abort",
      "(tip: call with --go to skip this check)",
      '   [type "go" to proceed]> '
    );
    
    my $in = <STDIN>;
    chomp($in);
    unless ($in && lc($in) eq 'go') {
      print "Didn't get 'go' -- exiting.\n";
      exit;
    }
  }
    
  my $ddl_text = $ddl->slurp;

  print "\n-->> calling system command:  sqlite3 " . $sqlt->relative . ' < ' . $ddl->relative . '  ';
  
  my $result = run_forked([$sqlite3,$sqlt], { child_stdin => $ddl_text });
  my $exit = $result->{exit_code};
  
  print " [exit: $exit]\n";
  die "\n" . $result->{err_msg} if ($exit);
  
  print "\n";
  
  # for good measure, make sure we're generating from $sqlt in the next step
  ($dsn,$user,$pass) = ("dbi:SQLite:$sqlt",'','');
}
[% END %]

my @connect = ($dsn,$user,$pass);
print "\nDumping schema \"$schema_class\" to \"" . file($applib)->resolve->relative . "\"\n";
print "[ " . join(' ',map { $_||"''" } @connect) . " ]\n\n";

DBIx::Class::Schema::Loader::make_schema_at(
  $schema_class, 
  {
    debug => 1,
    dump_directory => $applib,
    use_moose	=> 1, generate_pod => 0,
    components => ["InflateColumn::DateTime"],
  },
  [ 
    @connect,
    { loader_class => 'RapidApp::Util::MetaKeys::Loader' }
  ]
);

print "\n";

