#!/usr/bin/perl
#
#
# GnuLedger Install Script, Copyright (c) 2001-2002 GnuLedger Project
#
# Thanks to Kurt Telep and Dave Rich for their work on this.
#
#

use DBI;

##########################VERSION CONFIGURATION#####################################
$CURRENT_VERSION="0.4.0";
$OPERATING_SYSTEM="UNIX";
####################################################################################

# AddSlash Subroutine
# -------------------------------------------------
# Adds a slash to the end of pathnames if needed
# -------------------------------------------------
sub AddSlash($) {
	my $Pathname = shift;
	if ($Pathname !~ /\/$/) {
		$Pathname .= "/";
	}
	
	return $Pathname;
}

# CheckModule Subroutine
# -----------------------------------------------
# Verifies required module is installed
# -----------------------------------------------
sub CheckModule($) {
	my $ModName = shift;
	my $ModPath = $ModName;
	my $FoundMod = 0;
	$ModPath =~ s/::/\//g;
	foreach (@INC) {
		if (-e $_."/".$ModPath.".pm") {
			$FoundMod = 1;
		}
	}

	if ($FoundMod != 1) {
		die "Unable to locate module $ModName in \@INC, please verify it is installed\n"; 
	}
}	

# Require our other modules, so if any aren't there, we fail
# ------------------------------------------------------------
CheckModule('DBD::mysql');
CheckModule('Math::BigFloat');
CheckModule('Math::FixedPrecision');
CheckModule('Number::Format');

# Some globals
# ------------------------------------------------------------
my $GEN_DATE = localtime();
my $userin = "";
my %Dirs = ();
my $Virtualhost = 0;
my $VirtualDir;

print "GnuLedger $CURRENT_VERSION Setup\n\n";
print "Please respond to the following prompts to complete installation of GnuLedger\n\n";

print "Will GnuLedger be configured under a VirtualHost? [y/n]: ";
$userin = <STDIN>;
chomp($userin);
if ($userin =~ /y/i) {
	$VirtualHost = 1;
	print "\nPlease enter the location of the VirtualHost root (ex. /var/www/myvirtdir): ";
	$VirtualDir = <STDIN>;
	chomp($VirtualDir);

	if ($VirtualDir =~ /^$/) {
		print "You must enter a VirtualHost root directory, exiting..\n\n";
		exit;
	}

	if (! -e $VirtualDir) {
		print "\n$VirtualDir does not exist, create it? [y/n]: ";
		my $Create = <STDIN>;
		chomp $Create;
		if ($Create =~ /y/i) {
			mkdir ($VirtualDir,0755) || die "Unable to create $Virtualdir: $!\n";
			mkdir ("$VirtualDir/cgi-bin",0755) || die "Unable to create $Virtualdir/cgi-bin: $!\n";
		} else {
			print "Please create $VirtualDir manually then run the installer again\n\n";
			exit;
		}
	} elsif (! -e "$VirtualDir/cgi-bin") {
		print "\n$VirtualDir/cgi-bin does not exist, create it? [y/n]: ";
		my $Create = <STDIN>;
                chomp $Create;
                if ($Create =~ /y/i) {
                        mkdir ("$VirtualDir/cgi-bin",0755) || die "Unable to create $Virtualdir/cgi-bin: $!\n";
                } else {
                        print "Please create $VirtualDir/cgi-bin manually then run the installer again\n\n";
                        exit; 
                }
	}

	%Dirs = ( 'cgibin'	=> "/cgi-bin/",
		  'destdir'	=> "$VirtualDir/cgi-bin/",
		  'apacheroot'	=> "$VirtualDir" );

} else {
	# Dirs hash holds default directories for install
	%Dirs = ( 'cgibin'     => "/cgi-bin/", 
		     'destdir'    => "/var/www/cgi-bin/",
	     	     'apacheroot' => "/var/www/htdocs/" );

	print "Please enter cgi-bin location (Relative to the web root directory)[$Dirs{cgibin}]: ";
	$userin = <STDIN>;
	chomp($userin);
	if ($userin !~ /^$/){    # If something is input 
		$Dirs{cgibin} = AddSlash($userin);
	}

	print "Please enter the directory to install GnuLedger into [$Dirs{destdir}]: ";
	$userin = <STDIN>;
	chomp($userin);
	if ($userin !~ /^$/){    # If something is input 
		$Dirs{destdir} = AddSlash($userin);
	}

	print "Please enter the apache/httpd root directory [$Dirs{apacheroot}]: ";
	$userin = <STDIN>;
	chomp($userin);
	if ($userin !~ /^$/){    # If something is input 
		$Dirs{apacheroot} = AddSlash($userin);
	}

	# Check and make sure everything exists first
	# -------------------------------------------------
	if (! -e $Dirs{destdir}) {
		print "\n$Dirs{destdir} does not exist, shoft I create it? [y/n]: ";
		my $choice = <STDIN>;
		if ($choice =~ /y/i) {    # Create a dir structure
			my $cd = "";
			foreach ( split /\//,$Dirs{destdir} ) {
				$cd .= $_."/";
				if (! -e $cd) {
					print "Creating $cd\n";
					mkdir ($cd, 0755) || die "Unable to create $Dirs{$_}: $!\n";
				}
			}
		} else {
			print "Please create $Dirs{destdir} manually and rerun the installation script.\n";
		}
	}

	if (! -e $Dirs{apacheroot}) {
		print "\n$Dirs{apacheroot} does not exist, please verify and rerun the installation script.\n";
	}

}

print "----------------------------------------\n";
print "Installing GnuLedger With the Following \n";
print "\n";
print "         cgi-bin => $Dirs{cgibin}\n";
print " dest. directory => $Dirs{destdir}\n";
print "       html root => $Dirs{apacheroot}\n\n";
print "----------------------------------------\n";

$Output = `cp GL_ICONS.tar.gz $Dirs{apacheroot} ; cd $Dirs{apacheroot} ; tar zxvf GL_ICONS.tar.gz ;`;
$Output = `cp GL_PROGRAM.tar.gz $Dirs{destdir} ; cd $Dirs{destdir} ; tar zxvf GL_PROGRAM.tar.gz`;

#############################################################################
# This fix shouldn't be needed anymore -- I fixed the bug in tarup.sh -- Mike
# Fix because the icons go in the wrong directory
#$Output = `mv $Dirs{apacheroot}/GnuLedger-icons/* $Dirs{apacheroot};`;
##############################################################################

print "  Files Copied to $Dirs{destdir}\n";
print "----------------------------------------\n";

# TODO Verify valid servername...
print "Please enter the server name: ";
$SERVER_NAME = <STDIN>;
chomp($SERVER_NAME);

print "Use which compression program (zip / tar) [tar]: ";
$COMPRESS_PROG = <STDIN>;
chomp($COMPRESS_PROG);
if (!$COMPRESS_PROG) {
	$COMPRESS_PROG = 'tar';
}

print "mysql root password: ";
$SQL_PASS = <STDIN>;
chomp($SQL_PASS);

print "financial database [Finance]: ";
$DB = <STDIN>;
chomp($DB);
if (!$DB) {
	$DB = 'Finance';
}

print "\n----------------------------------------\n";
print "  Generating GNULEDGER.pm: ";

open (IN, "$Dirs{destdir}" . "GNULEDGER-SRC");
open (OUT, ">$Dirs{destdir}" . "GNULEDGER.pm");

$TopString = "
#!/usr/bin/perl
#/ GNULEDGER 0.3.xx SERIES - [$CURRENT_VERSION]
#
# Copyright (c) 2001-2002 GnuLedger Project <http://www.gnuledger.org>
#
# This program is released under the terms of the GNU General Public License.
#
# GNULEDGER.pm GENERATED ON $GEN_DATE
#
#
#////////////////////////////////////// INCLUDES /////////////////////////////////////////////////////

package GNULEDGER;
use DBI;
use Number::Format;

use GL_FUNC          qw(\%var);      # Database functions
use GL_GENERALLEDGER qw(\%var);      # Chart of Accounts/Ledger view
use GL_HELP          qw(\%var);      # Help System
use GL_HTML          qw(\%var);      # HTML Interface
use GL_INVENTORY     qw(\%var);      # Inventory specific functions
use GL_MODE          qw(\%var);      # Display/authentication functions
use GL_REPORTS       qw(\%var);      # Reporting functions
use GL_WAP           qw(\%var);      # WAP functions for WAP-enabled devices
use GL_XML           qw(\%var);      # XML System

	
use vars             qw(\%var \$WholeString \@Pairs \$Pair \$Field \$Data \$ckexists \@ISA \@EXPORT \@EXPORT_OK
                        \$usercookie \$passwordcookie \$header \@Missing \$Item \$i \$Module \@ActiveModules
			\$RetVal \@Modules \$Mode \@Trans \@Ref_Trans \$Trans \$Ref_Trans \$Query \$Cursor
			\$Command \$Instance \$Db_User \$Db_Pass \$Db);
use Exporter;

\@ISA            = qw(Exporter);
\@EXPORT         = qw();
\@EXPORT_OK      = qw(\%var);

use strict;
no strict 'refs';
#//////////////////////////////////////////////////////////////////////////////////////////////////////\n\n";

print OUT $TopString;
print OUT "
#//////////////////////////////////////////////////////////////////////////////////////////////////////
# INITENV: Sets the GnuLedger environment up for execution... provides critical values for the
# -------  program. Very important. Do not change. Is created when GnuLedger is installed.
#
sub initenv{

        \$var{'CURRENT_VERSION'}         = '$CURRENT_VERSION';
        \$var{'FLASH'}                   = 0;
        \$var{'SERVER_NAME'}             = '$SERVER_NAME';
        \$var{'LOCATION'}                = '$Dirs{cgibin}';
        \$var{'SCRNAME'}                 = 'GnuLedger';
        \$var{'TEMPLATE_DIR'}            = './GnuLedger-interface/';
        \$var{'DB'}                      = '$DB';
        \$var{'DB_TYPE'}                 = 'mysql'; #MySQL is the only db that has been tested so far.
        \$var{'GLBUSR'}                  = 'root';
        \$var{'GLBPASS'}                 = '$SQL_PASS';
        \$var{'SQL_DIR'}                 = './GnuLedger-SQL/';
        \$var{'HELP_DIR'}                = './GnuLedger-Help/';
        \$var{'FULL_PATH'}               = \"\$var{'LOCATION'}\" . \"\$var{'SCRNAME'}\";
        \$var{'HTTPD_ROOT'}              = \"$Dirs{apacheroot}\";
        \$var{'UPLOAD_PATH'}             = \"\$var{'LOCATION'}\" . \"GL_UPLOAD.pm\";
        \$var{'OS'}                      = \"$OPERATING_SYSTEM\";
	\$var{'COMPRESS'}		 = '$COMPRESS_PROG';

        # This is the global message. It is generally not needed, but there are instances
        # where I'm sure it can come in handy.
        \$var{'GLOBAL_MESSAGE'}          = '';
}
#/
#/////////////////////////////////////////////////////////////////////////////////////////////////////\n\n";


while (<IN>){
	print OUT $_;
}

print "Done\n";
print "  Setting Permissions: ";
system ("chmod 755 $Dirs{destdir}" . "GNULEDGER.pm");
print "Done\n";

close (IN);
close (OUT);

print "  Creating Database, if reinstalling please ignore any errors\n\n";
$dbh = DBI->connect("DBI:mysql:mysql:localhost", 'root', $SQL_PASS) || die $DBI::errstr;

print "  Creating Database $DB: ";
$Query = "CREATE DATABASE $DB";
$Cursor = $dbh -> prepare ($Query);
$Cursor -> execute;
$Cursor -> finish;
print "Done\n";
$dbh -> disconnect;


$dbh = DBI->connect("DBI:mysql:$DB:localhost", 'root', $SQL_PASS) || die $DBI::errstr; 

print "  Creating AccountList Table: ";
$Query = "CREATE TABLE AccountList (name varchar(20), parent varchar(20), atype varchar(20), astlia char(1))";
$Cursor = $dbh -> prepare($Query);
$Cursor -> execute;
$Cursor -> finish;
print "Done\n";

print "  Creating AccountTypes Table: ";
$Query = "CREATE TABLE AccountTypes (type varchar(20))";
$Cursor = $dbh -> prepare($Query);
$Cursor -> execute;
$Cursor -> finish;
print "Done\n";

print "  Creating User Table: ";
$Query = "CREATE TABLE userpriv (user varchar(30), pass varchar(50), adm char(1), rem char(1), ent char(1), edt char(1), accts blob)";
$Cursor = $dbh -> prepare($Query);
$Cursor -> execute;
$Cursor -> finish;
print "Done\n";

print "----------------------------------------\n";
print "\nNow we create an administrative user\n";
print "gnuledger user: ";
$User = <STDIN>;
chomp($User);

print "gnuledger password: ";
$Pass = <STDIN>;
chomp($Pass);
$Pass = crypt($Pass, ".1");

print "\n  Setting up admin user: ";
$Query = "SELECT user FROM userpriv WHERE user='$User'";
$Cursor = $dbh -> prepare ($Query);
$Cursor -> execute;
$Response = $Cursor -> fetchrow;
$Cursor -> finish;

if ($Response ne "$User"){
	$Query = "INSERT INTO userpriv (user, pass, adm, rem, ent, edt, accts) values ('$User', '$Pass', 'Y', 'Y', 'Y', 'Y', 'ALL')";
	$Cursor = $dbh -> prepare($Query);
	$Cursor -> execute;
	$Cursor -> finish;
}

print "Done\n";

print "  Creating Account types: ";
$Query = "SELECT type FROM AccountTypes WHERE type='Bank'";
$Cursor = $dbh -> prepare ($Query);
$Cursor -> execute;
$Response = $Cursor -> fetchrow;
$Cursor -> finish;

if ($Response ne 'Bank'){
	$Query = "INSERT INTO AccountTypes (type) values ('Bank')";
	$Cursor = $dbh -> prepare($Query);
	$Cursor -> execute;
	$Cursor -> finish;
}

$Query = "SELECT type FROM AccountTypes WHERE type='Credit_Card'";
$Cursor = $dbh -> prepare ($Query);
$Cursor -> execute;
$Response = $Cursor -> fetchrow;
$Cursor -> finish;

if ($Response ne 'Credit_Card'){

	$Query = "INSERT INTO AccountTypes (type) values ('Credit_Card')";
	$Cursor = $dbh -> prepare($Query);
	$Cursor -> execute;
	$Cursor -> finish;
}

$Query = "SELECT type FROM AccountTypes WHERE type='Expense'";
$Cursor = $dbh -> prepare ($Query);
$Cursor -> execute;
$Response = $Cursor -> fetchrow;
$Cursor -> finish;

if ($Response ne 'Expense'){

	$Query = "INSERT INTO AccountTypes (type) values ('Expense')";
	$Cursor = $dbh -> prepare($Query);
	$Cursor -> execute;
	$Cursor -> finish;
}

$Query = "SELECT type FROM AccountTypes WHERE type='Other_Asset'";
$Cursor = $dbh -> prepare ($Query);
$Cursor -> execute;
$Response = $Cursor -> fetchrow;
$Cursor -> finish;

if ($Response ne 'Other_Asset'){

	$Query = "INSERT INTO AccountTypes (type) values ('Other_Asset')";	
	$Cursor = $dbh -> prepare($Query);
	$Cursor -> execute;	
	$Cursor -> finish;
}

$Query = "SELECT type FROM AccountTypes WHERE type='Other_Liability'";
$Cursor = $dbh -> prepare ($Query);
$Cursor -> execute;
$Response = $Cursor -> fetchrow;
$Cursor -> finish;

if ($Response ne 'Other_Liability'){

	$Query = "INSERT INTO AccountTypes (type) values ('Other_Liability')";
	$Cursor = $dbh -> prepare($Query);
	$Cursor -> execute;
	$Cursor -> finish;
}

$dbh -> disconnect;

print "Done \n";
print "----------------------------------------\n";
print "  Cleaning up\n";
print "----------------------------------------\n";

system("rm -f $Dirs{destdir}" . "GL*.gz");
system("rm -f $Dirs{apacheroot}" . "GL*.gz");
system("rm -f $Dirs{destdir}" . "GNULEDGER-SRC");

if ($VirtualHost != 0) {
	print "You have configured GnuLedger under a Virtual Host\n";
	print "Below is a suggested VirtualHost stanza to insert\n";
	print "into your httpd.conf file\n\n";
	print "<VirtualHost *>\n\tServerAdmin your\@email.add\n\tDocumentRoot $VirtualDir\n\tServerName ";
	print "$SERVER_NAME\n\tScriptAlias /cgi-bin/ $VirtualDir/cgi-bin/\n</VirtualHost>\n";
	print "----------------------------------------\n";
}

print "  Finished Installation\n";
print "----------------------------------------\n";
exit;
