#!/usr/bin/perl -w

# Support functionality for the TWiki Collaboration Platform, http://TWiki.org/
#
# A script to help people upgrade an existing TWiki to a new version
#  (don't laugh - we're expecting applause, not laughter!)
#
# Jul 2004 - written by Martin Gregory, martin@gregories.net
# Changes copyright (C) 2005 Crawford Currie http://c-dot.co.uk
# Changes copyright (C) 2005 Sven Dowideit http://www.home.org.au
#

use strict;

use File::Spec;

=begin twiki

---+ UpgradeTwiki

Create an upgraded twiki installation from an existing one
and a new distribution.

=cut

my ( $mode ) = '';
my ( $oldCfgFile ) = '';
my ( $newCfgFile ) = '';
my ( $newDataDir ) = '';
my ( $oldDataDir ) = '';
my ( $outputDir ) = '';

if ( $#ARGV > -1 ) {
	if ( $ARGV[0] =~ /--(.*)/ ) {
		$mode = $1;
	}
}

if ( ( $#ARGV >= 1 ) && ($mode eq 'moveTopics') ) { # must be 2 parameters
        $newCfgFile = $ARGV[1] || die "missing parameter1\n\n"; 
} elsif ( ($mode eq 'upgradeTopics') && ($#ARGV == 4)) {
        $oldCfgFile = $ARGV[1] || die "missing newCfgFile\n\n"; 
        $newDataDir = $ARGV[2] || die "missing newDataDir\n\n"; 
        $oldDataDir = $ARGV[3] || die "missing oldDataDir\n\n"; 
        $outputDir = $ARGV[4] || die "missing outputDir\n\n"; 
	$newCfgFile = './bin/setlib.cfg';
} elsif ( (($mode eq 'cairo') || ($mode eq 'dakar')) && ($#ARGV == 2)) {
        $oldCfgFile = $ARGV[1] || die "missing oldSetLigFile / oldCfgFile\n\n"; 
        $outputDir = $ARGV[2] || die "missing outputDir\n\n"; 
	$newCfgFile = './bin/setlib.cfg';
} elsif ( ($mode eq '') && ($#ARGV == 1)) {		#do dakar & upgradeTopics
        $oldCfgFile = $ARGV[0] || die "missing oldCfgFile\n\n"; 
        $outputDir = $ARGV[1] || die "missing outputDir\n\n"; 
	$newCfgFile = './bin/setlib.cfg';
} else {
	printUsage();
    exit(1);
}

#set up the new libpath using the setlib.cfg file
    my ( $newCfgFileDir ) = '.';
    if ( $newCfgFile =~ /^(.+)\/[^\/]+$/ ) {
        $newCfgFileDir = $1;
    }
    # Set library paths in @INC
    unshift @INC, File::Spec->rel2abs( $newCfgFileDir );
    {
        use Cwd;
        my $current = cwd();
        chdir $newCfgFileDir;
        require 'setlib.cfg';
        chdir $current;
    }

	eval 'use TWiki';
	if ( $@ ) {
		die "Error finding TWiki.pm, please check your setlib.cfg file points to the lib dir using absolute paths\n\@INC contains: @INC\n";
	}
	print "\nLoaded TWiki version: $TWiki::VERSION\n";

#Make absolute paths from parameters
$oldDataDir = File::Spec->rel2abs( $oldDataDir ) ."/";
$newDataDir = File::Spec->rel2abs( $newDataDir ) ."/" ;
$outputDir = File::Spec->rel2abs( $outputDir ) ."/";
$oldCfgFile = File::Spec->rel2abs( $oldCfgFile );
$newCfgFile = File::Spec->rel2abs( $newCfgFile );

#TODO: this totally breaks the attempt to call the cairo upgrade code, as there was not setlib.cfg then
my $oldSetlibPath = $oldCfgFile;
if ( $oldCfgFile =~ /(.*)setlib.cfg/ ) {
    $oldSetlibPath = $1;
} else {
	$oldCfgFile .= '/setlib.cfg';
}

die "ERROR: old TWiki's setlib.cfg file not found at ($oldCfgFile)\n" unless (-e $oldCfgFile);


print "\nUpgradeTWiki called with: ($mode), oldCfgFile = ($oldCfgFile), newCfgFile = ($newCfgFile), outputDir = ($outputDir)\n";

if ( $mode eq '' ) 
{
	eval 'use TWiki::Upgrade';
	die "ERROR: $@" if ( $@ ); 
	my $upgradeObj = TWiki::Upgrade->new($outputDir);
	
	eval 'use TWiki::Upgrade::UpgradeToDakar';
	die "ERROR: $@" if ( $@ ); 
	my ($oldDataDir, $oldPubDir) = TWiki::Upgrade::UpgradeToDakar::doAllDakarUpgrades($upgradeObj, $oldSetlibPath, $outputDir);
	$oldDataDir = File::Spec->rel2abs( $oldDataDir );
	$oldPubDir = File::Spec->rel2abs( $oldPubDir );
	my $newTWikiDir = File::Spec->rel2abs( '.' );

	eval 'use TWiki::Upgrade::UpdateTopics';
	die "ERROR: $@" if ( $@ ); 
	TWiki::Upgrade::UpdateTopics::UpdateTopics($upgradeObj, $newTWikiDir.'/data/', $oldDataDir, $outputDir.'/data/');
	TWiki::Upgrade::UpdateTopics::UpdateTopics($upgradeObj, $newTWikiDir.'/pub/', $oldPubDir, $outputDir.'/pub/');
	TWiki::Upgrade::UpgradeToDakar::RemainingSteps($upgradeObj, $outputDir);
} 
elsif ( $mode eq 'dakar' ) 
{
        eval 'use TWiki::Upgrade';
        die "ERROR: $@" if ( $@ );
        my $upgradeObj = TWiki::Upgrade->new($outputDir);

        eval 'use TWiki::Upgrade::UpgradeToDakar';
        die "ERROR: $@" if ( $@ );
        my ($oldDataDir, $oldPubDir) = TWiki::Upgrade::UpgradeToDakar::doAllDakarUpgrades($upgradeObj, $oldSetlibPath, $outputDir);
        $oldDataDir = File::Spec->rel2abs( $oldDataDir );
        $oldPubDir = File::Spec->rel2abs( $oldPubDir );
        my $newTWikiDir = File::Spec->rel2abs( '.' );
}
elsif ( $mode eq 'cairo' ) 
{
	eval 'use TWiki::Upgrade::UpgradeToCairo';
	TWiki::Upgrade::UpgradeToCairo::doAllCairoUpgrades($newCfgFile, $oldCfgFile, $outputDir);
}
elsif ( $mode eq 'upgradeTopics' ) 
{
	if ((! -d $oldDataDir ) || (! -d $newDataDir)) 
	{
		print "\nnewDataDir & oldDataDir must exist\n";
		exit;
	}
	eval 'use TWiki::Upgrade';
	die "ERROR: $@" if ( $@ ); 
	my $upgradeObj = TWiki::Upgrade->new($outputDir);
	eval 'use TWiki::Upgrade::UpdateTopics';
	TWiki::Upgrade::UpdateTopics::UpdateTopics($upgradeObj, $newDataDir, $oldDataDir, $outputDir);
}
elsif ( $mode eq 'moveTopics' ) 
{
	eval 'use TWiki::Upgrade::MoveTopics';

    my ( $class, $method ) = @_;

    my ( $query, $pathInfo, $user, $url, $topic );
    my $scripted = 0;

	use CGI;
        $query = new CGI( "" );
        $scripted = 1;
        $user = "TWikiContibutor"; 	#TODO: this should be replaced by a generic AdminUser
        $url = "";
        $topic = "";
        $pathInfo = "";
        foreach my $arg ( @ARGV ) {
            if ( $arg =~ /^-user=(.*)$/o ) {
                $user = $1;
            }
            # parse name=value parameter pairs
            if ( $arg =~ /^-?([A-Za-z0-9_]+)=(.*)$/o ) {
                $query->param( $1=>$2 );
            } else {
                $pathInfo = $arg;
            }
        }
    my $session = new TWiki( $pathInfo, $user, $topic, $url,
                             $query, $scripted );


    TWiki::Upgrade::MoveTopics::moveTopics( $session );

#} elsif ( $mode eq '' ) {
}

sub printUsage {
	print <<EOUSAGE;

Create an upgraded twiki installation from an existing one and a new distribution.

usage: UpgradeTWiki <oldSetlibCfgFile> <outputDirectory>
   will run the --dakar option and then the --upgradeTopics option (transfers your existing config, and upgrades your topics and pub files into the outputDirectory (doesn not modify your existing directories)

usage: UpgradeTWiki --dakar <oldSetlibCfgFile> <outputDirectory>
   does the DakarRelease upgrade

usage: UpgradeTWiki --upgradeTopics <oldSetlibCfgFile> <newDataDir> <oldDataDir> <outputDirectory>
   just tries to merge changes from newTopics (uses patch to merge with user changes)

Note: if possible, point the cfgFile parameter to setlib.cfg, if it does not exist (or you can't find it) use TWiki.cfg.

EOUSAGE
}

#MOVED out of docco as they are heavily untested, and probably don't work now
#
#usage: UpgradeTWiki --cairo <oldCfgFile> <outputDirectory>
#does the CairoRelease upgrade (should end up incompatible with DakarRelease code)
#
#usage: UpgradeTWiki --moveTopics <newCfgFile>
#moves topics to the new Web layout (initially for DEVELOP) 
#WARNING: this needs to run on a functional install, and is not reversible (if it goes wrong)

