// Copyright (c) 2009, Jens Peter Secher <jpsecher@gmail.com>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

typedef Port =
{
	var branch : String;
	var version : String;
}

class MercurialPort
{
	public static function main()
	{
		logger = new Script();
		var port : Port = parseCommandLine();
		// Extract package information from the changelog file.
		Mercurial.switchToBranch( Constants.mainBranch(), logger );
		var changeLog = DebianChangeLog.parseCurrentChangeLog( logger );
		// Override version if specified on the command line.
		if( port.version != null )
		{
			changeLog = new DebianChangeLog( changeLog.source, port.version );
		}
		logger.info( 1, "Merging " + changeLog.version + " into " + port.branch );
		// Search for a tag matching the version.
		var tag = Util.fullTag( changeLog );
		if( ! Mercurial.hasTag( tag, logger ) )
		{
			Util.die
			(
				"No tag " + tag + " exists for version " + changeLog.version
			);
		}		
		// Merge the specified version into the port branch.
		Mercurial.switchToBranch( port.branch, logger );
		var merge = Mercurial.merge( tag, logger );
		for( line in merge )
		{
			// Filter out "(branch merge, don't forget to commit)".
			var dontForget = ~/don.t forget to commit/;
			if( ! dontForget.match( line ) ) logger.info( 1, line );
		}
		var msg = Constants.port() + " merged version "
			+ changeLog.version + " into " + port.branch;
		var commit = Mercurial.commit( msg, logger );
		for( line in commit ) logger.info( 1, line );
		logger.info( 0, "You are now in branch " + port.branch );
		logger.info( 0, "Use hg up default to get back to main development branch." );
	}

	//
	// Returns the branch and merge instructions from the parsed command-line
	// arguments.
	//
	static function parseCommandLine() : Port
	{
		var usage = "Usage: " + Constants.port() + " [-V|--version]" +
		" [-v|--verbose] [-p|--package-version packageversion] branch";
		var options = new GetPot( Sys.args() );
		Util.maybeReportVersion( options, usage );
		// Collect verbosity options.
		while( options.got( ["--verbose","-v"] ) ) ++logger.verbosity;
		var version : String = null;
		if( options.got( ["-p","--package-version"] ) )
		{
			version = options.next();
			if( version == null )
			{
				Util.die( "No package version specified." );
			}
		}
		// Reject other options.
		Util.exitOnExtraneousOptions( options, usage );
		// Get the branch name.
		var branch = options.unprocessed();
		if( branch == null ) Util.die( usage );
		// Reject other arguments.
		Util.exitOnExtraneousArguments( options, usage );
		Mercurial.exitIfUncommittedChanges( logger );
		return { branch: branch, version: version };
	}

	static var logger : Script;
}
