#!/usr/bin/perl -w

use strict;
use File::Copy;
use File::Find;
use LWP::UserAgent;

sub modify_file
{
    my ($fname, $fparams) = @_;

    unless (open F, $fname){
        print STDERR "postinstall: 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 STDERR "postinstall: can't open file `$fname` for writing\n";
        return 0;
    }
    print F $file_content;
    close F;
    return 1;
}


#########################
#	Quote Section	#
#########################

sub mysql_quote
{
    my ($qstr) = @_;
    # replace ' for \'
    # replace \ for \\
    $qstr =~ s/\\/\\\\/g;
    $qstr =~ s/'/\\'/g;
    return $qstr;
}

sub php_quote
{
    my ($qstr) = @_;
    # replace ' for \'
    # replace \ for \\
    $qstr =~ s/\\/\\\\/g;
    $qstr =~ s/'/\\'/g;
    return $qstr;
}

sub shell_quote
{
    my ($qstr) = @_;
    # replace ' for \'
    # replace \ for \\
    $qstr =~ s/\\/\\\\/g;
    $qstr =~ s/"/\\\"/g;
    $qstr =~ s/\$/\\\$/g;
    return $qstr;
}


sub parse_input_to_hash 
{ 
    my %params = (); 
    while (<STDIN>){ 
        my ($k,$v); 
        if (/^([^=]+)=(.+)$/){ 
            $v = $2; 
            chomp $v; 
            $k = $1; 
            $params{"$k"} = $v; 
        } 
    } 
    return %params; 
} 

sub parse_plesk_config_file
{
    my %psa_params = ();
    open PSACONF, '/etc/psa/psa.conf';
    print "opening psa config\n";
    while (<PSACONF>){
        chomp;
        unless (/^#/){
            if (/^(\s*[_a-zA-Z]+)\s+(.+?)\s*$/){
                # print "$1 : $2\n";
                $psa_params{$1} = $2;
            }
        }
    }
    close PSACONF;
    return %psa_params;
}

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

sub check_parameters
{
    my ($imp_params, %params) = @_;
    my $is_error = 0;
    foreach (@$imp_params){
        unless (check_parameter($_, %params)){
            print "postinstall: no parameter $_ specified for application\n";
            $is_error = 1;
        }
    }
    if ($is_error){
        exit 1;
    }
}


#############################
#	SSL Section	    #
#############################

sub get_proto
{
    my ($p_ssl_target_directory) = @_;
    my $proto;
    if ($p_ssl_target_directory eq 'true'){
            $proto = 'https://';
    } else {
            $proto = 'http://';
    }
    return $proto;
}

sub get_documents_directory
{
    my ($p_ssl_target_directory) = @_;
    my $documents_directory;
    if ($p_ssl_target_directory eq 'true'){
            $documents_directory = 'httpsdocs';
    } else {
            $documents_directory = 'httpdocs';
    }
    return $documents_directory;
}

sub get_ssl_enabled
{
    my ($p_ssl_target_directory) = @_;
    my $ssl_enabled;
    if ($p_ssl_target_directory eq 'true'){
            $ssl_enabled = 1;
    } else {
            $ssl_enabled = 0;
    }
    return $ssl_enabled;
}


#################################
#	Remote Databese Section	#
#################################

sub get_dbhost
{
    my ($p_dbhost) = @_;
    my $dbhost;
    if (defined $p_dbhost && $p_dbhost ne '') {
        $dbhost = $p_dbhost;
    } else {
        $dbhost = 'localhost';
    }
    return $dbhost;
}

sub get_dbport
{
    my ($p_dbport) = @_;
    my $dbport;
    if (defined $p_dbport && $p_dbport ne '') {
        $dbport = $p_dbport;
    } else {
        $dbport = '3306';
    }
    return $dbport;
}

sub get_dbremote_params
{
    my ($p_dbhost, $p_dbport) = @_;
    my $dbremote_params = '';
    my ($m_dbhost, $m_dbport);
    if (defined $p_dbhost && $p_dbhost ne '') {
        $m_dbhost = shell_quote($p_dbhost);
        $dbremote_params .= " --host=\"${m_dbhost}\" ";
    } else {
        $m_dbhost = shell_quote('localhost');
        $dbremote_params .= " --host=\"${m_dbhost}\" ";
    }
    if (defined $p_dbport && $p_dbport ne '') {
        $m_dbport = shell_quote($p_dbport);
        $dbremote_params .= " --port=\"${m_dbport}\" ";
    }
    return $dbremote_params;
}

sub get_dbstring
{
    my ($p_dbhost, $p_dbport) = @_;
    my $dbstring = '';
    my $dbhost = '';
    my $dbport = '';

    if (defined $p_dbhost && $p_dbhost ne '') {
        $dbhost = $p_dbhost;
    } else {
        $dbhost = 'localhost';
    }
    $dbstring .= $dbhost;
    if (defined $p_dbport && $p_dbport ne '') {
        $dbport = $p_dbport;
        $dbstring .= ":$dbport";
    }
    return $dbstring;
}


#################################
#	Path to root directory	#
#################################

sub get_root_dir
{
    my ($documents_directory, $p_vhost_path, $p_install_prefix) = @_;
    my $root_dir = '';
    $root_dir = $p_vhost_path.'/'.$documents_directory.'/'.$p_install_prefix;

    if($p_install_prefix eq "."){
        $root_dir =~ s/\/\.//g;
    }
    return $root_dir;
}

sub get_root_url
{
    my ($proto, $documents_directory, $p_domain_name, $p_install_prefix) = @_;
    my $root_url = '';
    $root_url = $proto.$p_domain_name."/".$p_install_prefix;

    if($p_install_prefix eq "."){
        $root_url =~ s/\/\.//g;
    }
    return $root_url;
}

sub get_root_url_cgi
{
    my ($proto, $documents_directory, $p_domain_name, $p_install_prefix) = @_;
    my $root_url_cgi = '';
    $root_url_cgi = $proto.$p_domain_name.'/'.'cgi-bin'.'/'.$p_install_prefix;

    if($p_install_prefix eq "."){
	$root_url_cgi =~ s/\/\.//g;
    }
    return $root_url_cgi;
}
				
				
sub get_root_dir_cgi
{
    my ($p_vhost_path, $p_install_prefix) = @_;
    my $root_dir_cgi = $p_vhost_path.'/'.'cgi-bin'.'/'.$p_install_prefix;

    if($p_install_prefix eq "."){
        $root_dir_cgi =~ s/\/\.//g;
    }
    return $root_dir_cgi;
}

sub get_install_prefix
{
    my ($p_install_prefix) = @_;
    my $install_prefix;
    if($p_install_prefix eq "."){
        $install_prefix = "";
    }
    else{
        $install_prefix = $p_install_prefix;
    }
    return $install_prefix;
}


#################################################
#	Modification of configuration files	#
#################################################

sub config_file_modification
{
    my ($pvhost_path, $app_config_template, $root_dir, $config_files, %config_params) = @_;
#    my $app_config_template = "app_config.template";
    if (-e "${root_dir}/${app_config_template}"){
        foreach my $config_file (@$config_files) {
            my $config_file_full = "${root_dir}/${config_file}";
            my $config_template = "${root_dir}/${app_config_template}";
            unless (open F, $config_template){
                print "can't open file `$config_template` for reading\n";
                return 0;
            }
            my $conf_templ_str;
            my $param_name;
            while (<F>){
                my $comma = 0;
                $conf_templ_str = $_;
                $conf_templ_str =~ s/\n//;
                ($param_name) = split(/=/,$conf_templ_str);
                if($param_name eq ''){
		    $comma = 1;
                    ($param_name) = split(/,/,$conf_templ_str);
                }
                ($param_name) =~ s/\$/\\\$/g;
                ($param_name) =~ s/\'/\\'/g;
                ($param_name) =~ s/\"/\\"/g;
                ($param_name) =~ s/\[/\\[/g;
                ($param_name) =~ s/\]/\\]/g;
                ($param_name) =~ s/\(/\\(/g;
                ($param_name) =~ s/\)/\\)/g;

                my $file_content = '';
                my $cur_str = '';
                unless (open F2, $config_file_full){
                    print "can't open file `$config_template` for reading\n";
                    return 0;
                }

                while (<F2>){
                   $cur_str = $_;
                    if($comma){
                        $cur_str =~ s/${param_name},[^\n]*/${conf_templ_str}/;
                    }
                    else{
                        $cur_str =~ s/${param_name}=[^\n]*/${conf_templ_str}/;
                    }
                    $file_content .= $cur_str;
                }
                close F2;
                unless (open F3, ">$config_file_full"){
                    print "can't open file `$config_file_full` for writing\n";
                    return 0;
                }
                print F3 $file_content;
                close F3;
            }
            unless (modify_file($config_file_full, \%config_params)){
                print STDERR "couldn't change file ${config_file_full}\n";
                exit 1;
            }
        }
        close F;
    }
    else{
        foreach my $config_file (@$config_files) {
            my $config_file_full = $pvhost_path."/mivadata/${config_file}";
            my $config_file_full_dist = ${config_file};
            $config_file_full_dist .= ".in";
            unless(-e "${root_dir}/${config_file_full_dist}"){
                $config_file_full_dist = $config_file;
                $config_file_full_dist =~ s/\.php/\.dist\.php/;
                $config_file_full_dist =~ s/\.html/\.dist\.html/;
                $config_file_full_dist =~ s/\.ini/\.dist\.ini/;
                $config_file_full_dist =~ s/\.inc/\.dist\.inc/;
                $config_file_full_dist =~ s/\.pl/\.dist\.pl/;
                $config_file_full_dist =~ s/\.dist\.inc\./\.inc\./;
                $config_file_full_dist =~ s/\.dist\.ini\./\.ini\./;
            }
            copy("${root_dir}/$config_file_full_dist", $config_file_full);
            unless (modify_file($config_file_full, \%config_params)){
                print STDERR "couldn't change file ${config_file_full}\n";
                exit 1;
            }
        }
    }
}

#########################################################################
#	Modification of schema files and database initialisation	#
#########################################################################

sub schema_file_modification
{
    my ($p_mysql_bin, $p_dbname, $p_dbuser, $p_dbpasswd, $dbremote_params, $root_dir, $schema_files, %sql_params) = @_;
    my $mysql_bin = $p_mysql_bin.'/mysql';
    my $m_dbname = shell_quote($p_dbname);
    my $m_dbuser = shell_quote($p_dbuser);
    my $m_dbpass = shell_quote($p_dbpasswd);

    foreach my $sql_file (@$schema_files) {
        my $sql_file_full = $sql_file;
        my $sql_file_full_temp = $sql_file.".sql";
        copy($sql_file_full, $sql_file_full_temp);	
        unless (modify_file($sql_file_full_temp, \%sql_params)){
            print STDERR "couldn't change file ${sql_file_full_temp}\n";
            exit 1;
        }
        my $mysql_cmd = "${mysql_bin} ${dbremote_params} -u\"${m_dbuser}\" -p\"${m_dbpass}\" \"${m_dbname}\" <${sql_file_full_temp}";
        my $str_res = `$mysql_cmd`;
        if ($?){
            # error occured during mysql
            print STDERR "unable to import sql data:\n${str_res}\n";
            print STDERR "$mysql_cmd\n";
            exit 1;
        }
        unlink($sql_file_full_temp);
    }
}


#################################################
#	set permissions for dirs and files	#
#################################################

sub set_permissions
{
    my ($root_dir, $perm_elems) = @_;
    foreach my $pe (keys %$perm_elems) {
        unless( chmod (oct($$perm_elems{$pe}),"$pe") ) {
            print STDERR "... couldnt chmod $pe";
        }
    }
}


#########################################
#	set mass permissions 		#
#########################################

sub set_recurse_permissions
{
    my ($root_dir, $mass_perm_el) = @_;
    foreach my $mpe (keys %$mass_perm_el) {
        find (sub {
            my $fname = $File::Find::name;
            my $fmod = 0;
	    chmod oct($$mass_perm_el{$mpe}), $fname;
        }, "${root_dir}/$mpe");
    }
}


#####################################################################################
#####################################################################################

my @imp_params = qw( vhost_path domain_name install_prefix ssl_target_directory admin_login admin_passwd first_name last_name email company address city state zip country phone fax license_number );
my $is_error=0;

#########################
#	Quote Section	#
#########################

my %params = parse_input_to_hash();
my %psa_params = parse_plesk_config_file();
check_parameters(\@imp_params, %params);

#############################
#	SSL Section	    #
#############################

my $proto = get_proto($params{'ssl_target_directory'});
my $documents_directory = get_documents_directory($params{'ssl_target_directory'});
my $ssl_enabled = get_ssl_enabled($params{'ssl_target_directory'});

#################################
#	Remote Databese Section	#
#################################

my $dbhost = get_dbhost($params{'dbhost'});
my $dbport = get_dbport($params{'port'});
my $dbremote_params = get_dbremote_params($params{'dbhost'}, $params{'port'});
my $dbstring = get_dbstring($params{'dbhost'}, $params{'dbport'});

#################################
#	Path to root directory	#
#################################

my $root_dir = get_root_dir($documents_directory, $params{'vhost_path'}, $params{'install_prefix'});
my $root_url = get_root_url($proto, $documents_directory, $params{'domain_name'}, $params{'install_prefix'});
my $root_url_cgi = get_root_url_cgi($proto, $documents_directory, $params{'domain_name'}, $params{'install_prefix'});
my $root_dir_cgi = get_root_dir_cgi($params{'vhost_path'}, $params{'install_prefix'});
my $install_prefix = get_install_prefix($params{'install_prefix'});

# If installation in docroot then chenge `install_prefix` from `.` to ``

#if(0){
#    $root_dir = $root_dir_cgi;
#}


#################################################
#	Modification of configuration files	#
#################################################

my @config_files = ( "setup.xml" );
my @config_files_cgi = (  );

my %config_params = (
   "PROTO" => php_quote($proto),
   "DB_HOST" => php_quote($dbhost),
   "DB_PORT" => php_quote($dbport),
   "DB_STRING" => php_quote($dbstring),
   "DOMAIN_NAME" => php_quote($params{'domain_name'}),
   "INSTALL_PREFIX" => php_quote($install_prefix),
   "ROOT_DIR" => php_quote($root_dir),
   "ROOT_URL" => php_quote($root_url),
   "ROOT_URL_CGI" => php_quote($root_url_cgi),
   "SSL_ENABLED" => php_quote($ssl_enabled),
   "SSL_MODE" => php_quote($params{'ssl_target_directory'}),
    
    "ADMIN_LOGIN" => php_quote($params{'admin_login'}),
    "ADMIN_PASS" => php_quote($params{'admin_passwd'}),
    "FIRST_NAME" => php_quote($params{'first_name'}),
    "LAST_NAME" => php_quote($params{'last_name'}),
    "EMAIL" => php_quote($params{'email'}),
    "COMPANY" => php_quote($params{'company'}),
    "ADDRESS" => php_quote($params{'address'}),
    "CITY" => php_quote($params{'city'}),
    "STATE" => php_quote($params{'state'}),
    "ZIP" => php_quote($params{'zip'}),
    "COUNTRY" => php_quote($params{'country'}),
    "PHONE" => php_quote($params{'phone'}),
    "FAX" => php_quote($params{'fax'}),
    "LICENSE_NUMBER" => php_quote($params{'license_number'}),
 );    

config_file_modification($params{'vhost_path'}, "app_config.template", $root_dir, \@config_files, %config_params);
config_file_modification($params{'vhost_path'}, "app_config.template", $root_dir_cgi, \@config_files_cgi, %config_params);

#################################################
#	set permissions for dirs and files	#
#################################################

my %perm_elems = (

);

set_permissions($root_dir, \%perm_elems);

my $link_cmd="";
if($proto eq "http://" && $params{'install_prefix'} ne "."){
    $link_cmd = "ln -s ".${root_dir}." ".$params{'vhost_path'}."/httpsdocs/".$install_prefix;
}
elsif($proto eq "http://" && $params{'install_prefix'} eq "."){
    $link_cmd = "ln -fs ".${root_dir}."/admin.mvc ".$params{'vhost_path'}."/httpsdocs/admin.mvc\n";
    $link_cmd .= " ln -fs ".${root_dir}."/5.00 ".$params{'vhost_path'}."/httpsdocs/5.00\n";
    $link_cmd .= " ln -fs ".${root_dir}."/graphics ".$params{'vhost_path'}."/httpsdocs/graphics\n";
    $link_cmd .= " ln -fs ".${root_dir}."/evalchecki.mvc ".$params{'vhost_path'}."/httpsdocs/evalchecki.mvc\n";
    $link_cmd .= " ln -fs ".${root_dir}."/evalcheckp.mvc ".$params{'vhost_path'}."/httpsdocs/evalcheckp.mvc\n";
    $link_cmd .= " ln -fs ".${root_dir}."/paylinki.mvc ".$params{'vhost_path'}."/httpsdocs/paylinki.mvc\n";
    $link_cmd .= " ln -fs ".${root_dir}."/paylinkp.mvc ".$params{'vhost_path'}."/httpsdocs/paylinkp.mvc\n";
    $link_cmd .= " ln -fs ".${root_dir}."/paypalc.mvc ".$params{'vhost_path'}."/httpsdocs/paypalc.mvc\n";
    $link_cmd .= " ln -fs ".${root_dir}."/paypali.mvc ".$params{'vhost_path'}."/httpsdocs/paypali.mvc\n";
    $link_cmd .= " ln -fs ".${root_dir}."/paypalp.mvc ".$params{'vhost_path'}."/httpsdocs/paypalp.mvc\n";
    $link_cmd .= " ln -fs ".${root_dir}."/remove.mvc ".$params{'vhost_path'}."/httpsdocs/remove.mvc\n";
}
elsif($proto eq "https://"){
#    $link_cmd = "ln -s ".${root_dir}." ".$params{'vhost_path'}."/httpdocs/".$install_prefix;
    $link_cmd = "true";
}
my $str_res_link = `$link_cmd`;

if ($?){
    # error occured during mysql 
    print STDERR "unable to get url:\n${str_res_link}\n";
    print STDERR "$link_cmd\n";
    exit 1;
}

my $t_mode = 0777;
my $orig_mod = 0755;
chmod $t_mode, $root_dir;
my $curl_cmd = "curl -k ".${root_url}."/setup.mvc?";

my $str_res_curl = `$curl_cmd`;

chmod $orig_mod, $root_dir;

if ($?){
    # error occured during mysql 
    print STDERR "unable to get url:\n${str_res_curl}\n";
    print STDERR "$curl_cmd\n";
    exit 1;
}
$_ = $str_res_curl;
if(/error/) {
    if(/License is not transferable/){
        print STDERR "\nLicense is not transferable\n\n";
    } elsif(/License Number does not exist/){
        print STDERR "\nLicense Number does not exist\n\n";
    } elsif(/Please enter the email address of the owner of this installation/){
	print STDERR "\nPlease enter the email address of the owner of this installation\n\n";
    } else{
        $str_res_curl =~ s/\n//g;
        $str_res_curl =~ s/<style.*<\/style>//g;
        $str_res_curl =~ s/<[^<>]*>//g;
        $str_res_curl .= "\n-----\n";
        print STDERR "\n${str_res_curl}\n";
    }
    exit 1;
}
elsif(/404 Not Found/){
    print STDERR "\nDomain name '".$params{'domain_name'}."' not found!\n\n";
    exit 1;
}

exit 0

