#!perl
# Upgrade from iWS 4.0
# Called by import.
#


BEGIN {
    $| = 1;
    $isNT = -d '\\';

    # global variables
    $useHTML = 0;
    $rootDir = 0;
    $instDir = 0;

    sub printError {
        my $msg = shift;

        if ($useHTML) {
            print "<FONT COLOR=\"red\">[Error]</FONT> $msg\n";
        } else {
            print $msg;
        }
        exit(1);
    }

    sub printUsage {

        print "Usage:  perl upgradeFrom40 -r <rootDir> [-i instance] [-w]\n\n";
        print "Where:  -r = root directory\n";
        print "        -i = name of instance to upgrade\n";
        print "        -w = output HTML\n";
        print "\n";
        exit(0);
    }


    # parse arguments
    if ($#ARGV < 0) {
        printUsage();
    }
    my $argc = 0;
    while ($argc <= $#ARGV) {
        if ($ARGV[$argc] eq "-r") {
            $argc++;
            if ($argc > $#ARGV) {
                printUsage();
            }
            $rootDir = $ARGV[$argc++];
            $rootDir =~ s/\\/\//g if $isNT;
            if (substr($rootDir, length($rootDir)-1, length($rootDir)) eq "/") {
                chop($rootDir);
            }
            if (!(-d $rootDir)) {
                printError("No such directory: $rootDir\n");
            }
        } elsif ($ARGV[$argc] eq "-i") {
            $argc++;
            if ($argc > $#ARGV) {
                printUsage();
            }
            $instDir = $ARGV[$argc++];
            $instDir =~ s/\\/\//g if $isNT;
            if (substr($instDir, length($instDir)-1, length($instDir)) eq "/") {
                chop($instDir);
            }
            if (!(-d "$rootDir/$instDir")) {
                printError("No such directory: $rootDir/$instDir\n");
            }
        } elsif ($ARGV[$argc] eq "-w") {
            $useHTML = 1;
            $argc++;
        } else {
            printUsage();
        }
    }
    # set include line
    @INC = ( "$rootDir/bin/https/perl" );
}
use BinUtil;
use Magnus;


# defines
my $JAVA_SEP = ":";
if ($isNT) {
    $JAVA_SEP = ";";
}

# environment
$ENV{LD_LIBRARY_PATH} = "$rootDir/bin/https/lib";
$ENV{SHLIB_PATH} = "$rootDir/bin/https/lib";
$ENV{LIBPATH} = "$rootDir/bin/https/lib";


# start upgrade...
# unless an instance is specified,
# deal with one-time installation-wide issues:
my %pkgList = BinUtil::getPkgList($rootDir);
if (!$instDir) {
    if ($isNT) {
        `$rootDir/bin/https/bin/regconfig -s MinorVersion 1`;
        if ($pkgList{'java'}) {
            my $classpath;
            chomp($classpath = `$rootDir/bin/https/bin/javaconfig -l NSES_CLASSPATH`);
            `$rootDir/bin/https/bin/regconfig -s NSES_CLASSPATH $classpath`;
        }
    } else {
        # in https-*, do:
        opendir(ROOTDIR, "$rootDir") or printError("Cannot open $rootDir: $!\n");
        while ($dirEntry = readdir(ROOTDIR)) {
            if ($dirEntry =~ /^https-/) {
                # first, fix rotate
                local *SRC;
                local *DEST;
                open(SRC, "$rootDir/$dirEntry/rotate") or
                    printError("Cannot open $rootDir/$dirEntry/rotate: $!\n");
                open(DEST, "> $rootDir/$dirEntry/rotate-new") or
                    printError("Cannot open $rootDir/$dirEntry/rotate-new: $!\n");
                while (<SRC>) {
                    if (/DATE=`date \+\%d\%h-\%I\%M\%p`/) {
                        print DEST "LANG=C ; export LANG\n";
                    }
                    print DEST;
                }
                close(SRC);
                close(DEST);
                rename("$rootDir/$dirEntry/rotate-new", "$rootDir/$dirEntry/rotate");
                # next, fix java files

            }
        }
        closedir(ROOTDIR);       
        # rename start-jre start-jvm and fix it
        my $fileName = "$rootDir/https-admserv/start-jre";
        if (-f $fileName) {
            my @data = ();
            my $jre_runtime_libpath;
            local *SRC;
            local *DEST;

            open(SRC, $fileName) or printError("Cannot read $fileName: $!\n");
            while (<SRC>) {
                if (/NSES_CLASSPATH/) {
                    # first, add NSES_SERVER_HOME
                    push(@data, "\# DO NOT CHANGE ANYTHING BELOW THIS LINE\n");
                    push(@data, "NSES_SERVER_HOME=$rootDir; export NSES_SERVER_HOME\n");
                    # then, fix NSES_CLASSPATH
                    my @line = split(/=/, $_);
                    my $classpath = $line[1];
                    @line = split(/;/, $classpath);
                    $classpath = removeFromClasspath($line[0],
                                                     "$rootDir/bin/https/jar/jsp.jar");
                    $classpath =~ s/$rootDir/\$\{NSES_SERVER_HOME\}/g;
                    $classpath = addToClasspath($classpath,
                                                '${NSES_SERVER_HOME}/bin/https/jar/jsp092.jar',
                                                '${NSES_SERVER_HOME}/bin/https/jar/NSJavaMiscUtil.jar',
                                                '${NSES_SERVER_HOME}/bin/https/jar/xml.jar',
                                                '${NSES_SERVER_HOME}/bin/https/jar/jspengine.jar');
                    $_ = "NSES_CLASSPATH=$classpath;$line[1]";
                }
                if (/LD_LIBRARY_PATH/) {
                    if (/^LD_LIBRARY_PATH=(.*?):\$\{LD_LIBRARY_PATH\};\s+export\s+LD_LIBRARY_PATH\s*$/) {
                        $jre_runtime_libpath=$1;
                        if ($jre_runtime_libpath =~ /PA_RISC/) {
                            $jre_runtime_libpath = '${NSES_JRE}/lib/PA_RISC/classic:' . $jre_runtime_libpath;
                        }
                        $_ = 'LD_LIBRARY_PATH=${NSES_JRE_RUNTIME_LIBPATH}:${LD_LIBRARY_PATH}; export LD_LIBRARY_PATH';
                    } else {
                        my @line = split(/:\$\{LD_LIBRARY_PATH\}/, $_);
                        $_ = "$line[0]:\$\{NSES_JRE_RUNTIME_LIBPATH\}:\$\{LD_LIBRARY_LIBPATH\}$line[1]";
                    }
                }
                push(@data, $_);
            }
            close(SRC);
            unlink($fileName);
            $fileName = "$rootDir/https-admserv/start-jvm";
            open(DEST, "> $fileName") or printError("Cannot write to $fileName: $!\n");
            my $line;
            foreach $line (@data) {
                if ($line =~ /\# DO NOT CHANGE/) {
                    if (defined($jre_runtime_libpath)) {
                        print DEST "NSES_JRE_RUNTIME_LIBPATH=$jre_runtime_libpath; export NSES_JRE_RUNTIME_LIBPATH\n";
                    } else {
                        print DEST "NSES_JRE_RUNTIME_LIBPATH=; export NSES_JRE_RUNTIME_LIBPATH\n";
                    }
                }
                print DEST $line;
            }
            close(DEST);
        }
        # set permissions for webpub
        if ($pkgList{'webpub'}) {
            my $dirEntry;
            my $magnus;
            my $userid = 0;
            my $done = 0;
            local *ROOTDIR;
            local *SRC;

            # look for first server with webpub turned on
            opendir(ROOTDIR, "$rootDir") or printError("Cannot open $rootDir: $!\n");
            while ($dirEntry = readdir(ROOTDIR)) {
                if ($dirEntry =~ /^https-/) {
                    next if ($dirEntry =~ /^https-admserv$/);
                    open(SRC, "$rootDir/$dirEntry/config/obj.conf") or
                        printError("Cannot open $rootDir/$dirEntry/config/obj.conf: $!\n");
                    while (<SRC>) {
                        if (/CM_Init/ || /es-search/) {
                            # fix permissions
                            $magnus = new Magnus("$rootDir/$dirEntry/config/magnus.conf");
                            if (!$magnus->value('User')) {
                                printError("No user specified in $rootDir/$dirEntry/config/magnus.conf.");
                            }
                            $userid = $magnus->value('User');
                            $done = 1;
                            last;
                        }
                    }
                    close(SRC);
                    last if $done;
                    if (!$userid) {
                        $magnus = new Magnus("$rootDir/$dirEntry/config/magnus.conf");
                        if (!$magnus->value('User')) {
                            printError("No user specified in $rootDir/$dirEntry/config/magnus.conf.");
                        }
                        $userid = $magnus->value('User');
                    }
                }
            }
            closedir(ROOTDIR);       
            my @userInfo = getpwnam($userid);
          BinUtil::recursiveChown($userInfo[2], $userInfo[3],
                                  "$rootDir/plugins/search/common/style");
        }
    }
    # remove old files
    unlink("$rootDir/bin/https/admin/html/svrcore.apm",
           "$rootDir/bin/https/httpadmin/html/svrcore.spm");
    # svrcore.[spm|apm] has been replaced with nescore.[spm|apm]
    if (-f "$rootDir/bin/https/admin/html/svrcore.apm") {
        unlink("$rootDir/bin/https/admin/html/svrcore.apm");
    }
    if (-f "$rootDir/bin/https/httpadmin/html/svrcore.spm") {
        unlink("$rootDir/bin/https/httpadmin/html/svrcore.spm");
    }
    # create new index files
    `$rootDir/bin/https/perl/perl $rootDir/bin/https/bin/createIndex -s $rootDir`;
    `$rootDir/bin/https/perl/perl $rootDir/bin/https/bin/createIndex -a $rootDir`;
    if ($isNT && !(-f"$rootDir/startconsole.url")) {
        # create url file
        my $svrName;
        my $svrPort;
        local *MAGNUS;
        open(MAGNUS, "$rootDir/https-admserv/config/magnus.conf") or 
            printError("Cannot open $rootDir/https-admserv/config/magnus.conf: $!\n.");
        while (<MAGNUS>) {
            if (/ServerName\s+(.*?)$/) {
                $svrName = $1;  
            } elsif (/Port\s+(\d+)/) {
                $svrPort = $1;  
            }
        }
        close(MAGNUS);
        local *URLFILE;
        open(URLFILE, "> $rootDir/startconsole.url") or
            printError("Could not create $rootDir/startconsole.url.\n");
        print URLFILE "[InternetShortcut]\n",
                      "URL=http://$svrName:$svrPort/\n";
        close(URLFILE);
    }
}

# now deal with individual servers:
if ($instDir) {
    upgradeServer($instDir);
} else {
    my $dirEntry;
    local *ROOTDIR;

    opendir(ROOTDIR, "$rootDir") or printError("Cannot open $rootDir: $!\n");
    while ($dirEntry = readdir(ROOTDIR)) {
        if ($dirEntry =~ /^https-/) {
            next if ($dirEntry =~ /^https-admserv$/);
            upgradeServer($dirEntry);
        }
    }
    closedir(ROOTDIR);
}

exit(0);



sub upgradeServer {
    my $dir = shift;
    my $fileName = "$rootDir/$dir/config/obj.conf";
    my @data = ();
    local *SRC;
    local *DEST;

    # add new config files
    `$rootDir/bin/https/perl/perl $rootDir/bin/https/bin/installResources -r $rootDir -i $dir`;
    # upgrade obj.conf
    if (!(-f $fileName)) {
        printError("Cannot find $fileName.\n");
    }
    open(SRC, $fileName) or printError("Cannot read $fileName: $!\n");
    while (<SRC>) {
        if (/Init/ && /fn=\"?livewireInit\"?/) {
            if (/LateInit/) {
                # make sure LateInit="yes"
                if (!(/LateInit=\"?yes\"?/)) {
                    s/LateInit=\"?(\w*)\"?/LateInit=\"yes\"/;
                }
            } else {
                # add LateInit
                chomp;
                $_ .= " LateInit=\"yes\"\n";
            }
        }
        push(@data, $_);
    }
    close(SRC);
    open(DEST, "> $fileName") or printError("Cannot write to $fileName: $!\n");
    print DEST @data;
    close(DEST);

    # upgrade jvm12.conf
    $fileName = "$rootDir/$dir/config/jvm12.conf";
    if (-f $fileName) {
        open(SRC, $fileName) or printError("Cannot read $fileName: $!\n");
        @data = ();
        while (<SRC>) {
            if (/^jvm.classpath/) {
                my @line = split(/=/, $_);
                $_ = "jvm.classpath=" . addToClasspath($line[1],
                                                       "$rootDir/plugins/samples/servlets/beans.10/SDKBeans10.jar");
            }
            push(@data, $_);
        }
        close(SRC);
        open(DEST, "> $fileName") or printError("Cannot write to $fileName: $!\n");
        print DEST @data;
        close(DEST);
    }
    # upgrade jvm.conf
    $fileName = "$rootDir/$dir/config/jvm.conf";
    if (-f $fileName) {
        open(SRC, $fileName) or printError("Cannot read $fileName: $!\n");
        @data = ();
        while (<SRC>) {
            if (/^jvm.classpath/) {
                my @line = split(/=/, $_);
                $_ = "jvm.classpath=" . addToClasspath($line[1],
                                                       "$rootDir/plugins/samples/servlets/beans.10/SDKBeans10.jar");
            }
            push(@data, $_);
        }
        close(SRC);
        open(DEST, "> $fileName") or printError("Cannot write to $fileName: $!\n");
        print DEST @data;
        close(DEST);
    }
    # create default java files
    if ($pkgList{'java'}) {
        my $rez;
        chomp($rez = `$rootDir/bin/https/bin/javaconfig -c $rootDir $dir`);
        if ($rez !~ /^Success/) {
            printError($rez);
        }
        # copy contexts.properties.default
        BinUtil::copyFile("$rootDir/$dir/config/contexts.properties.default",
                          "$rootDir/$dir/config/contexts.properties");
        # XXX: deal with ExtraPath in magnus.conf???
    }
}

exit;


sub removeFromClasspath {
    my $classpath = shift;
    my @classList = split(/$JAVA_SEP/, $classpath);
    my @pathList = @_;
    my @newClassList = ();
    my $pPath;
    my $cPath;

    foreach $pPath (@pathList) {
        foreach $cPath (@classList) {
            if ($cPath ne $pPath) {
                push(@newClassList, $cPath);
            }
        }
        @classList = @newClassList;
        @newClassList = ();
    }
    $classpath = "";
    foreach $cPath (@classList) {
        $classpath .= "$cPath$JAVA_SEP";
    }
    chop($classpath);
    return $classpath;
}


sub addToClasspath {
    my $classpath = shift;
    my @pathList = @_;
    my $pPath;

    foreach $pPath (@pathList) {
        $classpath .= "$JAVA_SEP$pPath";
    }
    return $classpath;
}
