#!/usr/bin/env perl

use strict;
use warnings;
use FindBin qw($Bin);
use lib "$Bin/";
use SB::Defaults qw($CONFIG $SB_CONFIG $SB_PREFIX);
use SB::Utils qw(parseIni writeIni checkParameters configHashDifference changeOwner);
use SB::Update qw(updateModules updateTemplates updateLocales);
use Getopt::Long;
use SB::Logging qw($Logger INFO DEBUG FATAL ERROR WARNING);
use POSIX qw(strftime);
require SB::Migration;
require SB::OS;

sub printHelpItem {
	my ($option, $comment, $value, $boolean) = @_;
	if ($boolean) {
		if ($value) { $value = "yes"; }
		else { $value = "no"; }
	}
	format  =
@<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
" --$option",			 $comment . ($value ? " [$value]" : "")
.
	write;
}

sub printHelp($) {
	my $config = shift;
	print "Usage: \n";
	printHelpItem("phpcli_path", "PHP CLI executable", $config->{'internal'}->{'phpcli_path'});
	printHelpItem("phpcgi_path", "PHP CGI executable", $config->{'internal'}->{'phpcgi_path'});

	printHelpItem("update_locales", "Update locales", "no");
	printHelpItem("update_templates", "Update templates", "no");
	printHelpItem("update_modules", "Update modules", "no");
	
	printHelpItem("migrate_all", "Migrate all sites", "no");
	printHelpItem("help", "Show this help", "no");
	printHelpItem("verbose", "Be verbose", "no");
	printHelpItem("[no]use_rewrite", "Enable/disable mod_rewrite usage", $config->{'general'}->{'use_rewrite'}, 1);
	
	printHelpItem("sb_admin_passwd", "Password for admin user", "not changed by default");
	
	printHelpItem("db_host", "MySQL database remote host", $config->{'database'}->{'host'});
	printHelpItem("db_port", "MySQL database remote port", $config->{'internal'}->{'db_port'});
	printHelpItem("db_admin_name", "MySQL administrator username", $config->{'internal'}->{'db_admin_name'});
	printHelpItem("db_admin_passwd", "MySQL administrator password", $config->{'internal'}->{'db_admin_passwd'});

	printHelpItem("sb_db_user_name", "SiteBuilder MySQL username", $config->{'database'}->{'username'});
	printHelpItem("sb_db_user_passwd", "SiteBuilder MySQL password");
	printHelpItem("sb_db_name", "SiteBuilder database name", $config->{'database'}->{'dbname'});

	printHelpItem("httpd_port", "Webserver port", $config->{'internal'}->{'httpd_port'});
	printHelpItem("sb_host_ip", "Create virtual host on the specified IP", $config->{'internal'}->{'sb_host_ip'});	
	printHelpItem("sb_hostname", "SiteBuilder virutal host name", $config->{'internal'}->{'sb_hostname'});
	printHelpItem("httpd_owner", "Webserver user and group", $config->{'internal'}->{'httpd_owner'});
	printHelpItem("[no]enable_ssl", "Enable/disable SSL", $config->{'internal'}->{'enable_ssl'}, 1);

	return;
}

sub updateWebServerConfig() {
	my $status;
	$Logger->Log(INFO, "Creating webserver config");
	$status = SB::Update::makeVHost();
	if ($status) {
		$Logger->Log(ERROR, "Webserver configuration failed");
	}
}

sub updateDBUser {
    if (SB::Update::createSBDatabaseUser()) {
		$Logger->Log(FATAL, "Cannot update SiteBuilder database user");
	}
}

sub updateDBStructure {
	$Logger->Log(INFO, "Creating SiteBuilder database");
	my $ret = SB::Update::createSBDatabase();
	return unless $ret;
	if ($ret == 2) {
		$Logger->Log(INFO, "Database already exists");
	}
}

sub main() {
	my $currentConfig = parseIni($SB_CONFIG, $SB::Defaults::CONFIG);
	my $config = SB::Defaults::makeConfigCopy($currentConfig);

	my $help = 0;
	my $verbose = 0;
	my $update_templates = 0;
	my $update_modules = undef;
	my $update_locales = 0;
	my $without_restart = 0;
	my $force = 0;
	my $migrate_all = 0;
	my $force_write_apache = 0;
	my $force_create_db = 0;
	my $log_file;
	my $merge_config;
	my $skip_log_name = 0;
	my $sb_prefix;

	Getopt::Long::Configure(qw(gnu_compat));
	my $result = GetOptions(
		#php options
		"phpcli_path=s"		=> \$config->{'internal'}->{'phpcli_path'},
		"phpcgi_path=s"		=> \$config->{'internal'}->{'phpcgi_path'},

		#flags
		"without_restart"	=> \$without_restart, 	#obsolete
		"update_locales"	=> \$update_locales,
		"update_modules:s"	=> \$update_modules,
		"update_templates"	=> \$update_templates,
		"force"				=> \$force,				#deprecated
		"migrate_all"		=> \$migrate_all,
		"help"				=> \$help,
		"verbose"			=> \$verbose,

		"force_update_wscfg"=> \$force_write_apache, #internal
		"force_update_db"	=> \$force_create_db,    #internal
		"merge_config:s"	=> \$merge_config,  	 #internal
		"skiplogname"		=> \$skip_log_name, 	 #internal
		"prefix=s"			=> \$sb_prefix, 		 #internal
		"logfile=s"			=> \$log_file,			 #internal

		#db options
		"db_host=s"			=> \$config->{'database'}->{'host'},
		"sb_db_user_name=s" => \$config->{'database'}->{'username'},
		"sb_db_user_passwd:s" => \$config->{'database'}->{'password'},
		"sb_db_name=s"		=> \$config->{'database'}->{'dbname'},
		"db_type=s"			=> \$config->{'database'}->{'adapter'}, # obsolete

		"db_port=s"			=> \$config->{'internal'}->{'db_port'},
		"db_admin_name=s"	=> \$config->{'internal'}->{'db_admin_name'},
		"db_admin_passwd:s" => \$config->{'internal'}->{'db_admin_passwd'},
		"ext_ip=s"			=> \$config->{'internal'}->{'ext_ip'}, #obsolete?

		#admin password
		"sb_admin_passwd=s" => \$config->{'internal'}->{'sb_admin_passwd'},

		#httpd options
		"httpd_port=i"		=> \$config->{'internal'}->{'httpd_port'},
		"sb_hostname=s"		=> \$config->{'internal'}->{'sb_hostname'},
		"httpd_owner=s"		=> \$config->{'internal'}->{'httpd_owner'},
		"sb_host_ip=s"		=> \$config->{'internal'}->{'sb_host_ip'},
		"enable_ssl!"		=> \$config->{'internal'}->{'enable_ssl'},
		"use_rewrite!"		=> \$config->{'general'}->{'use_rewrite'},
	);

	if ($help || !$result) {
		printHelp($config);
		return;
	}

	unless ($log_file) {
		my $time = strftime "%y%m%d%H%M", localtime;
		$log_file = $SB::Defaults::SB_PREFIX . "/tmp/sb_config-$time.log";
	}

	$Logger->init($log_file);
	if ($verbose) {
		$Logger->setLevel(DEBUG);
	}

	if ($skip_log_name) {
		$Logger->setShowLogName(0);
	}

	my $phpinidir = SB::OS::getInstallPrefix() . "/etc";
	unless ( -f $phpinidir . "/php.ini" ) {
		$Logger->Log(ERROR, "php.ini not found in $phpinidir, SiteBuilder may malfunction");
	} 
	else {
		$ENV{'PHPRC'} = $phpinidir;
	}

	$Logger->Log(WARNING, "'--without_restart' option is obsolete") if $without_restart;
	$Logger->Log(WARNING, "'--force' option is deprecated") if $force;

	# :FIXME: 20070416 
	# during upgrade db password from old config file will override the one
	# passed in command line
	if (defined($merge_config)) {
		unless ($merge_config) {
			$Logger->Log(DEBUG, "No old config specified, using config.bkp if any");
			$merge_config = $SB_PREFIX . "/" . "config.bkp";
		}
		if (-e $merge_config) {
			$Logger->Log(INFO, "Merging old config: $merge_config");
			$config = parseIni($merge_config, $config);
		}
	}

	$SB::Defaults::CONFIG = $config;

	checkParameters();

	my $difference = configHashDifference($currentConfig, $config);
	my $dbUpdate = 0;
	my $apacheUpdate = 0;
	my $adminUpdate = 0;

	foreach my $key qw(internal:enable_ssl internal:httpd_port
						internal:sb_host_ip internal:phpcgi_path
						internal:phpcgi_config) {
		last if ($apacheUpdate ||= exists($difference->{$key}));
	}
	$apacheUpdate ||= ($force_write_apache || $force);

	foreach my $key qw(database:host database:username database:dbname database:password) {
		last if ($dbUpdate ||= exists($difference->{$key}));
	}
	$dbUpdate ||= ($force_create_db || $force);

	foreach my $key qw(internal:sb_admin_passwd) {
		last if ($adminUpdate ||= exists($difference->{$key}));
	}

	if (defined($update_modules)) {
		if ($update_modules eq '') { 
			$update_modules = [ ];
		}
		else {
			my @update_modules = split(',', $update_modules);
			$update_modules = \@update_modules;
			if (ref($update_modules) eq "SCALAR") {
				$update_modules = [ $$update_modules ];
			}
		}
	}

	if ($dbUpdate) {
		updateDBUser();
		updateDBStructure();
		$adminUpdate = 1;
		$update_locales = $update_templates = 1;
		unless (defined($update_modules)) {
			$update_modules = ["ImageGallery", "Blogger"];
		}
	}

	if ($adminUpdate) {
		SB::Update::updateAdmin();
	}

	if ($apacheUpdate) {
		updateWebServerConfig();
	}
	$config = $SB::Defaults::CONFIG;
	$config->{'general'}->{'vz'} = 1 if SB::Utils::detectVZ();
	delete $config->{'internal'}->{'sb_admin_passwd'};
	delete $config->{'internal'}->{'phpiniupdate'};
	delete $config->{'internal'}->{'force'};
	delete $config->{'internal'}->{'without_restart'};
	writeIni($SB_CONFIG, $config);
	unlink ("$SB_PREFIX/options") if (-e "$SB_PREFIX/options");
	SB::Update::updateSitebuilderConf();

	if ( -e "$SB_PREFIX/migrate" ) {
		my $status = SB::Migration::performMigration();
		SB::Utils::changeOwner($CONFIG->{'internal'}->{'httpd_owner'});
		unlink("$SB_PREFIX/migrate") if $status == 0;
	}

	if ($migrate_all) {
		SB::Migration::migrateAllSites();
	}

	if ($update_locales) {
		updateLocales();
	}

	if ($update_templates) {
		updateTemplates();
	}

	if ($update_modules) {
		updateModules($update_modules);
	}
	#$Logger->Log(INFO, "SiteBuilder configuration finished");
}

main();

