#!/usr/bin/perl -w

use strict;
use File::Path;
use File::Copy;

my %params;
my %psa_params;
my @imp_params = qw( vhost_path domain_name install_prefix ssl_target_directory  oscommerce_dbuser oscommerce_dbpasswd oscommerce_dbname oscommerce_admin_login oscommerce_admin_passwd );
my $is_error=0;

sub print_out
{
    my ($text) = @_;
    print STDERR $text;
}

sub check_parameter
{
    my ($param) = @_;
    unless (defined $params{$param}){
        return 0;
    } else {
        return 1;
    }
}
sub modify_file
{
    my ($fname, $fparams) = @_;

    unless (open F, $fname){
        print_out "reconfigure: can't open file `$fname` for reading\n";
        return 0;
    }

    my $file_content;
    while (<F>){
        $file_content .= $_;
    }
    close F;

    my ($k,$v);
    while (($k,$v)=each(%$fparams)){
        $file_content =~ s/\@\@${k}\@\@/$v/g;
    }

    unless (open F, ">$fname"){
        print_out "reconfigure: can't open file `$fname` for writing\n";
        return 0;
    }
    print F $file_content;
    close F;
    return 1;
}


sub mysql_quote
{
    my @params = @_;
    my $size = @params;
    if (0 == $size) {
        return;
    }

    my $i;

    for ($i=0; $i<$size; $i++) {
        unless (defined $params[$i]) {
            $params[$i] = '';
        } else {
            # replace ' for \'
            # replace \ for \\
            $params[$i] =~ s/\\/\\\\/g;
            $params[$i] =~ s/'/\\'/g;
        }
    }
    if (wantarray( )) {
        return @params;
    } elsif (defined wantarray( )) {
        return $params[0];
    } else {
        return;
    }
}
sub php_quote
{
    my @params = @_;
    my $size = @params;
    if (0 == $size) {
        return;
    }

    my $i;

    for ($i=0; $i<$size; $i++) {
        unless (defined $params[$i]) {
            $params[$i] = '';
        } else {
            # replace ' for \'
            # replace \ for \\
            $params[$i] =~ s/\\/\\\\/g;
            $params[$i] =~ s/'/\\'/g;
        }
    }
    if (wantarray( )) {
        return @params;
    } elsif (defined wantarray( )) {
        return $params[0];
    } else {
        return;
    }
}


sub shell_quote
{
    my @params = @_;
    my $size = @params;
    if (0 == $size) {
        return;
    }

    my $i;

    for ($i=0; $i<$size; $i++) {
        unless (defined $params[$i]) {
            $params[$i] = '';
        } else {
            # replace ' for \'
            # replace \ for \\
            $params[$i] =~ s/\\/\\\\/g;
            $params[$i] =~ s/"/\\\"/g;
            $params[$i] =~ s/\$/\\\$/g;
        }
    }
    if (wantarray( )) {
        return @params;
    } elsif (defined wantarray( )) {
        return $params[0];
    } else {
        return;
    }
}


# parse input to hash
while (<STDIN>){
    my ($k,$v);
    if (/^([^=]+)=(.+)$/){
        $v = $2;
        chomp $v;
        $k = $1;
        $params{"$k"} = $v;
    }
}

# parse plesk config file
open PSACONF, '/etc/psa/psa.conf';
while (<PSACONF>){
    chomp;
    unless (/^#/){
        if (/^(\s*[_a-zA-Z]+)\s+(.+?)\s*$/){
            $psa_params{$1} = $2;
        }
    }
}
close PSACONF;

# check important parameters
foreach (@imp_params){
    unless (check_parameter($_)){
        print_out "reconfigure: parameter `$_` not found\n";
        $is_error = 1;
    }
}

if ($is_error){
    exit 1;
}

# remote DB checking
my ($dbhost, $dbport, $dbremote_params, $dbhostport);
$dbremote_params = '';
$dbhost = 'localhost';
$dbhostport = $dbhost;

if (defined $params{'dbhost'} && $params{'dbhost'} ne '') {
    my ($m_dbhost, $m_dbport);

    $dbhost = $params{'dbhost'};
    $m_dbhost = shell_quote($dbhost);
    $dbremote_params = " --host=\"${m_dbhost}\" ";
    $dbhostport = $dbhost;

    if (defined $params{'dbport'} && $params{'dbport'} ne '') {
        $dbport = $params{'dbport'};
        $dbhostport .= ":${dbport}";
        $m_dbport = shell_quote($dbport);
        $dbremote_params .= " --port=\"${m_dbport}\" ";
    }
}

# check SSL
my $ssl_enable;
my $documents_directory;
my $proto;
if ($params{'ssl_target_directory'} eq 'true'){
    $documents_directory = 'httpsdocs';
    $ssl_enable = 1;
	$proto = 'https';
} else {
    $documents_directory = 'httpdocs';
    $ssl_enable = 0;
	$proto = 'http';
}

# set base variables
if ($params{'install_prefix'} eq '.') {
	$params{'install_prefix'} = ''
} else {
	$params{'install_prefix'} = '/' . $params{'install_prefix'};
}
my $root_dir = $params{'vhost_path'}.'/'.$documents_directory.$params{'install_prefix'};
my $docs_dir = $params{'vhost_path'}.'/'.$documents_directory;
my $server_url = $proto . '://' . $params{domain_name};
my $app_url = $server_url.$params{'install_prefix'};
my $config_file = "${root_dir}/includes/configure.php";
my $config_file_in = $config_file . '.in';


# generate config file
my %config_params = (
    'DBNAME'        => php_quote($params{oscommerce_dbname}),
    'DBHOSTPORT'    => php_quote($dbhostport),
    'DBUSER'        => php_quote($params{oscommerce_dbuser}),
    'DBPASSWD'      => php_quote($params{oscommerce_dbpasswd}),
	'SERVER_URL'		=> php_quote($server_url),
	'ENABLE_SSL'	=> 'false',
	'DOMAIN_NAME'	=> php_quote($params{domain_name}),
	'INSTALL_PREFIX'	=> php_quote($params{install_prefix})
);
if ($ssl_enable) {
	$config_params{ENABLE_SSL} = 'true';
}

unless (copy($config_file_in, $config_file)) {
    print_out "couldn't copy config file\n";
    exit 1;
}

unless (modify_file($config_file, \%config_params)) {
    print_out "couldn't change file ${config_file}\n";
    exit 1;
}

# generate admin config file
$config_file = "${root_dir}/admin/includes/configure.php";
$config_file_in = $config_file . '.in';

$config_params{DOCS_ROOT} = php_quote($docs_dir);

unless (copy($config_file_in, $config_file)) {
    print_out "couldn't copy config file\n";
    exit 1;
}

unless (modify_file($config_file, \%config_params)) {
    print_out "couldn't change file ${config_file}\n";
    exit 1;
}



# Manage security
my $admin_htaccess_file = $root_dir . '/admin/.htaccess';
my $admin_htaccess_file_in = $admin_htaccess_file . '.in';
my $admin_htpasswd_file = $root_dir . '/admin/.htpasswd';
my $HTTPD_BIN_D = $psa_params{HTTPD_BIN_D};
my @ht_bins = ($HTTPD_BIN_D.'/htpasswd2', $HTTPD_BIN_D.'/htpasswd', '/usr/sbin/htpasswd2', '/usr/sbin/htpasswd');
my $htpasswd_bin = '';

foreach (@ht_bins) {
	if (-x $_) {
		$htpasswd_bin = $_;
	}
}

if ($htpasswd_bin eq '') {
	print_out "Unable to find `htpasswd` binary";
	exit 1;
}

# create .htaccess file
unless (copy $admin_htaccess_file_in, $admin_htaccess_file) {
	print_out "Unable to create file `.htaccess`!\n";
	exit 1;
}
my %htaccess_params = (
	'ROOT_DIR'	=> $root_dir
);

unless (modify_file($admin_htaccess_file, \%htaccess_params)) {
    print_out "couldn't modify file ${admin_htaccess_file}\n";
    $is_error = 1;
}

unless (unlink $admin_htpasswd_file) {
	print_out "Unable to delete .htpasswd file. It's impossible to change admin password.";
	exit 1;
}
my $cmd;
$cmd = "${htpasswd_bin}  -cb  ${admin_htpasswd_file} ";
$cmd .= shell_quote($params{oscommerce_admin_login});
$cmd .= ' "' . shell_quote($params{oscommerce_admin_passwd}) .'" ';
if (system($cmd) != 0) {
	print_out "Unable to create file `.htpasswd`\n";
	$is_error = 1;
}

# chmod files
unless (chmod 0777, $root_dir . '/tmp') {
	print_out "Unable to chmon directory for temporary files";
	$is_error = 1;
}

# delete temporary and installation files
rmtree "${root_dir}/install";
if (-e "${root_dir}/install") {
	print_out "unable to delete installation directory `${root_dir}/install`. Please remove it manually";
	$is_error = 1;
}

if ($is_error) {
	exit 1;
}
