#!/usr/bin/perl
package LedgerSMB::Scripts::dirt;
use warnings;
use strict;

use DBI;
use Getopt::Long;
use LedgerSMB;
use LedgerSMB::Database;
use LedgerSMB::Sysconfig;

# Default variable values section

my $owner = 'ledgersmb';
my $pass = 'LEDGERSMBINITIAL';
my $host = 'localhost';
my $port = '5432';
my $srcdir = `pwd`;
chomp $srcdir;
my $dstdir = `pwd`;
chomp $dstdir;
my $coa = "$srcdir/sql/coa/us/chart/General.sql";
my $chart_name;
my $gifi;
my $countrycode = 'US';
my $company_name = '';
my $postgres_username = 'postgres';
my $postgres_password;
my $postgres_db = 'postgres';
my $pgsql_contrib_dir = 'ignore';
my $ADMIN_FIRSTNAME = 'Default';
my $ADMIN_MIDDLENAME = 'NULL';
my $ADMIN_LASTNAME = 'Admin';
my $ADMIN_USERNAME = 'admin';
my $ADMIN_PASSWORD = 'admin';
my $progress = '';
my $help;

# Usage explanation section

my $usage = qq{
usage: $0 --company COMPANY --pgsql-contrib DIR [option1 .. optionN]

This script wants to be run as the root user. If you don't, you'll be
asked to enter the password of the 'postgres' user

This script creates a 'ledgersmb' user on the specified PostgreSQL host,
if it does not exist.  Then it proceeds to load the LedgerSMB database
structure and content, loading Chart of Accounts data and GIFI data
as specified in the argument list.

After the database has been created, the script inserts a default user
'$ADMIN_USERNAME' (password: '$ADMIN_PASSWORD'), with these initial values:

First name:  $ADMIN_FIRSTNAME  (NULL == none)
Middle name: $ADMIN_MIDDLENAME (NULL == none)
Last name:   $ADMIN_LASTNAME   (NULL == none)
Country:     'US'

This default user will be assigned all privileges within the application.

Available options:
 --srcdir		The path where the sources for LedgerSMB are located
			[$srcdir]
 --dstdir		The path where the sources will be located when invoked
			from the webserver [$dstdir]
 --host			The PostgreSQL host to connect to (see 'man psql') [$host]
 --port			The PostgreSQL port to connect to (see 'man psql') [$port]
 --pgsql_contrib	The directory where the tsearch2.sql, pg_trgm.sql and
			tablefunc.sql PostgeSQL are located [$pgsql_contrib_dir] [*]
 --company		The name of the database to be created for the company [*]
 --countrycode		The name of the 2 character country code. Defaults to 'US'
 --owner		The name of the superuser which is to become owner of the
			company's database [$owner]
 --password		The password to be used to create the 'ledgersmb' user
			on the specified PostgreSQL server [$pass]
 --coa			The path locating the file to be used to load the
			Chart of Accounts data
			Defaults to '$srcdir/sql/coa/us/chart/General.sql'
 --chart		Chart used
 --gifi			The path locating the file to be
			used to load the GIFI data with the chart of accounts
 --postgres_username	postgres username, only use if not 'postgres'
 --postgres_password	postgres user password. Defaults to none
 --postgres_db		postgres database name. Defaults to 'postgres'
 --progress		Echoes the commands executed by the script during setup
 --help			Shows this help screen

 * These arguments don't have a default, but are required
};

GetOptions (
	'srcdir:s' => \$srcdir,
	'dstdir:s' => \$dstdir,
	'host:s' => \$host,
	'port:i' => \$port,
	'pgsql_contrib=s' => \$pgsql_contrib_dir,
	'company=s' => \$company_name,
	'owner:s' => \$owner,
	'password:s' => \$pass,
	'coa:s' => \$coa,
	'chart:s' => \$chart_name,
	'gifi:s' => \$gifi,
	'countrycode:s' => \$countrycode,
	'postgres_username:s' => \$postgres_username,
	'postgres_password=s' => \$postgres_password,
	'postgres_db:s' => \$postgres_db,
	'progress' => \$progress,
	'help|?|h' => \$help
);
use lib qw($srcdir);
if ($help) {
	print $usage;
	exit;
}

unless ($company_name) {
	print $usage;
	print "\nmissing or empty --company option\n";
	exit;
}

unless ($postgres_password) {
	print $usage;
	print "\nmissing or empty --postgres_password option\n";
	exit;
}
unless (stat "/tmp/ledgersmb") {
	mkdir "/tmp/ledgersmb";
}
my $logger = Log::Log4perl->get_logger('LedgerSMB::Scripts::dirt');
my $creds = dirt_get_credentials();
my $request = {};
$request->{database} = 'ledgersmb';

$ENV{SCRIPT_NAME} = "dirt.pl";
# ENVIRONMENT NECESSARY
$ENV{PGUSER} = $creds->{login};
$ENV{PGPASSWORD} = $creds->{password};
$ENV{PGDATABASE} = $request->{database};

create_ledgersmb_httpd_conf();
my $dbh = DBI->connect("DBI:Pg:dbname=$postgres_db;host=$host;port=5432", $postgres_username, $postgres_password, {'RaiseError' => 0, pg_enable_utf8 => 1 });

my $is_v9_1plus_aref = $dbh->selectcol_arrayref("SELECT version();");
if ($progress) {
	print "$$is_v9_1plus_aref[0]\n";
}
unless ($$is_v9_1plus_aref[0] =~ /PostgreSQL 9\.[1-9]/) {
	$ENV{PG_CONTRIB_DIR} = "/usr/local/share/postgresql/extension/";
	if ($progress) {
		print "PostgreSQL < 9.1.x\n";
	}
}
my $admin_user_ok = $dbh->do("CREATE ROLE $creds->{login} WITH SUPERUSER LOGIN NOINHERIT ENCRYPTED PASSWORD '$creds->{password}';");
my $database = LedgerSMB::Database->new(
					{username => $creds->{login},
					company_name => $request->{database},
					password => $creds->{password}}
					);
if ($progress) {
	print "username $creds->{login}\n";
	print "company_name = $request->{database}\n";
	print "password = $creds->{password}\n";
}

my $rc = $database->create();#TODO what if createdb fails?
$logger->info("create rc=$rc");
my $mc = $database->load_modules('LOADORDER');
if ($progress) {
	print "\$mc = $mc\n";
}
$logger->info("load modules mc=$mc");
$database->process_roles('Roles.sql');

  # Load a chart of accounts
$dbh->disconnect;

$dbh = DBI->connect("DBI:Pg:dbname=$request->{database};host=$host;port=5432", $creds->{login}, $creds->{password}, {'RaiseError' => 0, pg_enable_utf8 => 1 });

my $psql_args = "-h $host -p $port -U $creds->{login}";
my $psql_cmd = "psql $psql_args -d $request->{database}";

  # Load a chart of accounts

if ($coa ne 'none') {
	open(my $psql_ph, "| $psql_cmd >/dev/null 2>&1")    || die "can't run psql: $!";
	open (my $coa_fh, "<", $coa);
	while (<$coa_fh>) {
		print $psql_ph $_;
		if ($progress) {
			print $_;
		}
	}
	close $coa_fh;
	close $psql_ph;
}
  # Load a gifi

if ($gifi) {
	open(my $psql_ph, "| $psql_cmd >/dev/null 2>&1")    || die "can't run psql: $!";
	open (my $gifi_fh, "<", $gifi);
	while (<$gifi_fh>) {
		print $psql_ph $_;
		if ($progress) {
			print $_;
		}
	}
	close $gifi_fh;
	close $psql_ph;
}
my $cmd="SELECT code FROM language;";
my @languages;
undef my $vetor;
my $sth = $dbh->prepare($cmd);
	$sth->execute;
while ($vetor = $sth->fetchrow) {
	push @languages, $vetor;
}
$sth->finish;

my @results = `tools/generate-language-table-contents.pl locale/po`;
#print @results;

$dbh->do("COPY language FROM STDIN WITH DELIMITER '|'");
for my $result (@results) {
	if (grep(/$result/, @languages)) {
		next;
	}
	$dbh->pg_putcopydata($result);
	if ($progress) {
		print $result;
	}
}
$dbh->pg_putcopyend();

my $SQL = "SELECT admin__save_user(NULL,
                         person__save(NULL,
                                      3,
                                      '$ADMIN_FIRSTNAME',
                                      '$ADMIN_MIDDLENAME',
                                      '$ADMIN_LASTNAME',
                                      (SELECT id FROM country
                                       WHERE short_name = 'US')),
                         '$ADMIN_USERNAME',
                         '$ADMIN_PASSWORD',
                         TRUE);

SELECT admin__add_user_to_role('$ADMIN_USERNAME', rolname)
FROM pg_roles
WHERE rolname like 'lsmb_${company_name}_%';";

	my $ir = $dbh->do($SQL);
	if($ir) {
		if ($progress) {
			print qq{Success for CREATE ADMIN_USER $ADMIN_USERNAME\n};
		}
	} else {
		print qq{Failure for CREATE ADMIN_USER $ADMIN_USERNAME -- $DBI::errstr\n};
		exit;
	}



sub dirt_get_credentials {
my $return_value = {};
#$logger->debug("\$auth=$auth");#be aware of passwords in log!
($return_value->{login}, $return_value->{password}) = ('ledgersmb', 'LEDGERSMBINITIAL');
if (defined $LedgerSMB::Sysconfig::force_username_case){
if (lc($LedgerSMB::Sysconfig::force_username_case) eq 'lower'){
$return_value->{login} = lc($return_value->{login});
} elsif (lc($LedgerSMB::Sysconfig::force_username_case) eq 'upper'){
$return_value->{login} = uc($return_value->{login});
}
}

return $return_value;

}

sub create_ledgersmb_httpd_conf {
open (my $tmpl_fh, "<", "$srcdir/ledgersmb-httpd.conf.template");
open (my $lhttpconf_fh, ">", "$dstdir/ledgersmb-httpd.conf");

my @tmpl = <$tmpl_fh>;
$logger->info("Creating $dstdir/ledgersmb-httpd.conf\n");
if ($progress) {
	print "Creating $dstdir/ledgersmb-httpd.conf\n";
}
for my $line (@tmpl) {
	$line =~ s/WORKING_DIR/$dstdir/g;
	$logger->info("$line");
	if ($progress) {
		print "$line";
	}
	print $lhttpconf_fh $line;
}
close $tmpl_fh;
close $lhttpconf_fh;
}


1;
