#!/usr/bin/perl -w
use strict;
use Cwd;

show_introduction();

while(1) {

	my ($response) = 
	promptyn("Would you like to continue?");

	if (!$response) {

		print "\nInstallation script terminated!\n\n";

		exit;
	}

	last;
}

my (%DATABASE_CFG) = ();

check_mysql();

$DATABASE_CFG{"INSTALLATION_DIRECTORY"} =
prompt_installation_directory();

my ($SLASH) = "/";

$SLASH = "\\"
if ($DATABASE_CFG{"INSTALLATION_DIRECTORY"} =~ /\\/);

#These are the directories and files required to setup the database
my (@manifest) = (
"mysql${SLASH}create.sql",
"mysql${SLASH}administration.sql",
"mysql${SLASH}administrators.sql",
"mysql${SLASH}alphabet.sql",
"mysql${SLASH}dictionary.sql",
"mysql${SLASH}hits.sql",
"mysql${SLASH}misses.sql",
"mysql${SLASH}parts_of_speech.sql",
"mysql${SLASH}pronunciation.sql",
"mysql${SLASH}requests.sql",
"mysql${SLASH}searches.sql",
"mysql${SLASH}tasks.sql"
);

my (@modified_manifest) = ();

print "Verifying setup directories and files...\n\n";

#Now verify files and directories
foreach(@manifest) {

	my ($path) = $_;

	$path =
	$DATABASE_CFG{INSTALLATION_DIRECTORY} . $SLASH. $path;

	push(@modified_manifest, $path);

	print "${path} ";

	show_error("\nCan't find ${path}", -1) if (!-e "$path"); 

	print "[OK]\n";
}

$DATABASE_CFG{"DB_HOST"} =
prompt("What is the name or IP address of the database server?");

$DATABASE_CFG{"DB_NAME"} =
prompt("What name do you want to give the dictionary database?"); 

$DATABASE_CFG{"DB_USER"} =
prompt("What name do you want to give the dictionary database user?");

$DATABASE_CFG{"DB_PASSWORD"} =
prompt("What will be $DATABASE_CFG{DB_USER}'s password?"); 

#Verify that configuration values given are correct before
#proceeding
while(1) {

	print "\n[VERIFY THESE VALUES]\n\n";

	foreach(sort(keys(%DATABASE_CFG))) {

		my ($name) = $_;

		my ($value) = $DATABASE_CFG{$name};

		print "${name} = ${value}\n";
	}

	my ($response) =
	promptyn("Are these values correct?");

	if (!$response) {

		print "\nInstallation script terminated!\n\n";

		exit;
	}

	last;
}

create_database(
$DATABASE_CFG{"DB_HOST"},
$DATABASE_CFG{"DB_NAME"},
$DATABASE_CFG{"DB_USER"},
$DATABASE_CFG{"DB_PASSWORD"}, \@modified_manifest);

#----------------------------------------------------------------------------
#Trys to run mysql to see if can be found.  If can't then it will terminate
#script.
#----------------------------------------------------------------------------
sub check_mysql {

	my (@output) = `mysql --help`; 
	my ($found_mysql_flag) = 0;

	print "Verifying mySQL path...\n";
 
	foreach(@output) {

		my ($o) = $_;

		trim(\$o);

		if (($o =~ /Usage/) || ($o =~ /mysql/)) {

			$found_mysql_flag++;
		} 
	}

	if ($found_mysql_flag >= 2) {

		print "Found it!\n";

	} else {

		show_error(
		"Can't execute 'mysql' at the command line.", -1);
	} 

	return;
}
#----------------------------------------------------------------------------
#Attempts to create the database and permissions at the command line;
#----------------------------------------------------------------------------
sub create_database {

	my ($dbhost) = shift;
	my ($dbname) = shift;
	my ($dbuser) = shift;
	my ($dbpwd) = shift;
	my ($sql_files) = shift;
	my ($rc);

	print 
	"Creating database ${dbname} on ${dbhost} " .
	"for user ${dbuser}...\n";

	my ($sql) = 
	"DROP DATABASE IF EXISTS ${dbname};" .
	"CREATE DATABASE ${dbname};" .
	"USE ${dbname};" .
	"GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP " .
	"ON ${dbname}.* TO ${dbuser}\@${dbhost} IDENTIFIED BY '${dbpwd}';";

	$rc = system("echo \"${sql}\" | mysql");

	show_error("\nA problem occurred when creating database.", -1) 
		if ($rc);

	print "Loading tables and data...\n\n"; 

	foreach(@$sql_files) {

		my ($sql_file) = $_;

		print "Loading ${sql_file}...\n";
		
		my ($mysql) =
		"mysql -u ${dbuser} -h ${dbhost} " .
		"--database=${dbname} --password=${dbpwd} " .
		"< \"${sql_file}\"";

		$rc = system(${mysql});

		show_error(
		"\nA problem occurred while loading tables " .
		"and/or data.", -1) if ($rc);
	}

	print "Database successfully created!\n\n"; 

	return;
}
#----------------------------------------------------------------------------
#Returns the basename of a path
#----------------------------------------------------------------------------
sub get_basename {

	my ($path) = shift;
	my (@path_tree) = shift;

	if ($path =~ /\\/) {

		@path_tree = split(/\\/, $path);

		return($path_tree[$#path_tree]);

	} elsif ($path =~ /\//) {

		@path_tree = split(/\//, $path);

		return($path_tree[$#path_tree]);
	}

	return($path);
}
#----------------------------------------------------------------------------
#Generic prompt 
#----------------------------------------------------------------------------
sub prompt {

	my ($prompt) = shift;
	my ($required_flag) = shift;
	my ($response) = "";

	#Iterate until correct response is found
	while(1) {

		#Show prompt message
		print "\n${prompt}\n\n";

		#Grab response
		$response = <STDIN>;

		#Remove leading and trailing white-spaces
		trim(\$response);
		
		if (($response) eq "" && ($required_flag)) {

			show_error("This parameter requires a value!", 0);
	
			next;
		} 

		last;
	}

	return($response);
}
#----------------------------------------------------------------------------
#Prompt for installation directory
#----------------------------------------------------------------------------
sub prompt_installation_directory {

	my ($pwd) = cwd();
	my ($default_dir) = "";
	my ($installation_directory) = "";

	if ($pwd) {

		if (-d "$pwd") {

			show_error(
			"You must run this installation script " .
			"under the same directory that it resides.", -1)
				if ($pwd !~ /bahasa\/utilities$/);

			$default_dir = $pwd;

			$default_dir =~ s/\/utilities$//;
		} 
	}

	if (-d "$default_dir") {

		while(1) {

			$installation_directory =
			promptx(
			"Enter the installation directory:\n", 
			"$default_dir", 1);
	
			if (!-d "$installation_directory") {

				show_error(
				"'${installation_directory}'" .
				" does not exists.  Please try again.", 0);

				next;
			}

			last;
		}

	} else {


		while(1) {
	
			$installation_directory =
			prompt("Enter the installation directory: ", 1);

			if (!-d "$installation_directory") {

				show_error(
				"'${installation_directory}'" .
				" does not exists.  Please try again.", 0);

				next;
			}

			last;
		}
	}

	#Remove trailing slash for UNIX systems if exists
	$installation_directory =~ s/\/$//;

	#Remove trailing slash for Windows systems if exists
	$installation_directory =~ s/\\$//;

	return("$installation_directory");
}
#----------------------------------------------------------------------------
#Generic yes or no prompt 
#----------------------------------------------------------------------------
sub promptyn {

	my ($prompt) = shift;
	my ($response);
	my ($ucresponse);
	my (%responses) = (YES => 1, NO => 1, Y => 1, N => 1);

	#Iterate until correct response is found
	while(1) {

		#Show prompt message
		print "\n${prompt} [y|n]\n\n";

		#Grab response
		$response = <STDIN>;
		
		#Clean leading and trailing white spaces
		trim(\$response);

		if ($response eq "") {

			show_error(
			"Please respond with a 'y' or 'n' answer!", 0);

			next;

		}  else {

			$ucresponse = uc($response);

			if (exists($responses{$ucresponse})) {

				last;

			} else {

				show_error(
				"Please respond with a 'y' or 'n' answer!", 0);
			}
		}
	}

	return(1) if ($ucresponse =~ /^Y/);

	return(0);
}
#----------------------------------------------------------------------------
#Generic prompt with default
#----------------------------------------------------------------------------
sub promptx {

	my ($prompt) = shift;
	my ($default) = shift;
	my ($required_flag) = shift;
	my ($response) = "";

	#Iterate until correct response is found
	while(1) {

		print "\n${prompt} [${default}]\n\n";

		$response = <STDIN>;

		chomp($response);

		if ($response eq "") {

			$response = $default;

			last;

		} else {

			trim(\$response);

			if (($response) eq "" && ($required_flag)) {

				show_error(
				"This parameter requires a value!", 0);

				next;

			} else {


				last;
			}
		}
	}

	return("$response");
}
#----------------------------------------------------------------------------
#Display error message then terminate script
#----------------------------------------------------------------------------
sub show_error {

	my ($msg) = shift;
	my ($exit_flag) = shift || 0;

	print "\nInstallation Error:\n${msg}\n\n";

	exit(-1) if ($exit_flag);

	return;
}
#----------------------------------------------------------------------------
#Introduction message
#----------------------------------------------------------------------------
sub show_introduction {

	print "\n\n";

	print "-" x 77;

	print "\n";

	print <<EOF;
[BAHASA INDONESIA DICTIONARY DATABASE CREATION]

The purpose of this script is to assist you 
with creating the mySQL database for the 
Bahasa Indonesia Dictionary. 

This script assumes that you have MYSQL 
installed and running on this system.

I've tried to make this script as portable 
as possible.  If for some reason this script 
fails then you will have to create the 
database manually.  See documentation 
for more details. 

Please feel free to modify this script to best 
fit your needs.

You can abort this script at any time by 
pressing CTRL C.

EOF

	print "-" x 77;

	print "\n";

	return;
}
#----------------------------------------------------------------------------
#Trim leading and trailing white-spaces from string token.  Pass token by
#reference only.
#----------------------------------------------------------------------------
sub trim {

	my ($token) = shift;

	return if (!$token);

	$$token =~ s/^\s+//;
	$$token =~ s/\s+$//;

	return;
}
#----------------------------------------------------------------------------
#----------------------------------------------------------------------------

