#!/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
#    I'm the one to blame for it being broken at the moment (27-Mar-2005)
#

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)) {
        $newCfgFile = $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"; 
} elsif ( (($mode eq 'cairo') || ($mode eq 'dakar')) && ($#ARGV == 3)) {
        $newCfgFile = $ARGV[1] || die "missing newCfgFile\n\n"; 
        $oldDataDir = $ARGV[2] || die "missing oldDataDir\n\n"; 
        $outputDir = $ARGV[3] || die "missing outputDir\n\n"; 
} 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 {
	print <<EOUSAGE;

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

usage: UpgradeTWiki 
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 --cairo <newCfgFile> <oldCfgFile> <outputDirectory>
does the CairoRelease upgrade (should end up incompatible with DakarRelease code)

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

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

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)

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
        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, $newCfgFileDir;
    unshift @INC, $newCfgFileDir.'/../lib';	#TODO: make sure its not a relative path
    {
        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";
	}
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 );

my $oldSetlibPath = $oldCfgFile;
if ( $oldCfgFile =~ /(.*)setlib.cfg/ ) {
    $oldSetlibPath = $1;
} else {
	$oldCfgFile .= '/setlib.cfg';
}

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


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

if ( $mode eq '' ) 
{
#run --dakar then --upgradeTopics
	eval 'use TWiki::Upgrade::UpgradeToDakar';
	die "ERROR: $@" if ( $@ ); 
	my ($oldDataDir, $oldPubDir) = TWiki::Upgrade::UpgradeToDakar::doAllDakarUpgrades($oldSetlibPath, $outputDir);
	$oldDataDir = File::Spec->rel2abs( $oldDataDir );
	$oldPubDir = File::Spec->rel2abs( $oldPubDir );
	my $newTWikiDir = File::Spec->rel2abs( '.' );
#	print "===========$oldDataDir\n============$oldPubDir\n";
	eval 'use TWiki::Upgrade::UpdateTopics';
	TWiki::Upgrade::UpdateTopics::UpdateTopics($newTWikiDir.'/data/', $oldDataDir, $outputDir.'/data/');
	TWiki::Upgrade::UpdateTopics::UpdateTopics($newTWikiDir.'/pub/', $oldPubDir, $outputDir.'/pub/');
	TWiki::Upgrade::UpgradeToDakar::RemainingSteps($outputDir);
} 
elsif ( $mode eq 'dakar' ) 
{
	eval 'use TWiki::Upgrade::UpgradeToDakar';
	if ( $@ ) {
		print "error: $@ \n";
		return;
	}
	TWiki::Upgrade::UpgradeToDakar::doAllDakarUpgrades($oldSetlibPath, $outputDir);
	TWiki::Upgrade::UpgradeToDakar::RemainingSteps($outputDir);
}
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::UpdateTopics';
	TWiki::Upgrade::UpdateTopics::UpdateTopics($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 = "PeterThoeny"; 	#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 '' ) {
}
