/*
Copyright (c) 2003-2008, Frederico Caldeira Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/

( function()
{
	var releaser = new CKRELEASER.releaser();
	CKRELEASER.verbose = true;

	// Run tests.
	var passCount = 0, failCount = 0;

	function assertEquals( expected, actual, title )
	{
		if ( expected != actual )
		{
			var error = {
				expected :expected,
				actual :actual
			};

			print( 'FAILED: ' + (title ? title : "") );

			if ( !error.expected )
				throw error;

			print( '  Expected: ' + error.expected );
			print( '  Actual  : ' + error.actual );

			failCount++;
		}
		else
			passCount++;
	}

	function error( msg )
	{
		print( msg );
		quit();
	}

	CKRELEASER.release.ignore = [ '.svn', '.settings', '.project' ];

	function prepareTempDirs()
	{
		var tempDir = new File( 'tmp' );

		if ( tempDir.exists() && !CKRELEASER.io.deleteDirectory( 'tmp' ) )
			error( "Can't delete temp directory" );

		if ( !tempDir.mkdir() )
			error( "Can't create temp directory: " + tempDir );

		var tests = [ 'directives', 'skins', 'samples', 'bom', 'lineendings', 'plugins' ];

		for ( var i = 0 ; i < tests.length ; i++ )
		{
			tempDir = new File( 'tmp/' + tests[i] );
			if ( !tempDir.mkdir() )
				error( "Can't create temp directory: " + tempDir );
		}
	}

	function testDirectives()
	{
		print( "\nTesting directives\n" );

		CKRELEASER.version = "3.1beta";
		CKRELEASER.timestamp = "AB89";

		var name = 'directives';
		var testName, tempFile, correctFile, sampleFile;

		var dir = new File( '_assets/directives' );
		var dirList = dir.list();

		for ( var i = 0 ; i < dirList.length ; i++ )
		{
			var f = new File( dir, dirList[i] );

			if ( dirList[i].indexOf( ".correct." ) == -1 )
				continue;

			testName = dirList[i].replace( ".correct.txt", "" );

			sampleFile = new File( '_assets/' + name + '/' + testName + '.txt' );
			correctFile = new File( '_assets/' + name + '/' + testName + '.correct.txt' );
			tempFile = new File( 'tmp/' + name + '/' + testName + '.out.txt' );

			CKRELEASER.io.copy( sampleFile, tempFile );
			releaser.processDirectives( tempFile );

			assertEquals( CKRELEASER.io.readFile( correctFile ), CKRELEASER.io.readFile( tempFile ),
					'releaser.directives[' + testName + ']' );
		}
	}

	function testSkins()
	{
		print( "\nTesting skins\n" );

		CKRELEASER.release.skins.source = '_assets/skins';
		CKRELEASER.release.skins.target = 'tmp/skins';

		var name = 'skins';
		var correctFile, dir, dirList, test, tempFile;

		var skinProcessor = new CKRELEASER.skinProcessor();
		skinProcessor.createSkins( '.', '.' );

		var sourceDir = new File( CKRELEASER.release.skins.source );
		var sourceDirList = sourceDir.list();

		for ( var i = 0 ; i < sourceDirList.length ; i++ )
		{
			if ( sourceDirList[i] == ".svn" || sourceDirList[i] == "CVS" )
				continue;

			dir = new File( CKRELEASER.release.skins.target, sourceDirList[i] );
			assertEquals( true, dir.exists(), dir + " exists?" );

			dirList = dir.list();
			assertEquals( true, dirList.length > 0, dir + " not empty?" );

			var foundCorrect = 0;
			var foundCss = 0;
			/**
			 * Loop through files in the target directory and search for valid
			 * CSS files
			 */
			for ( var j = 0 ; j < dirList.length ; j++ )
			{
				if ( dirList[j].indexOf( ".css" ) != -1 )
					foundCss++;

				if ( dirList[j].indexOf( "correct.txt" ) != -1 )
				{
					foundCorrect++;
					test = dirList[j].replace( ".correct.txt", "" );

					correctFile = new File( dir, dirList[j] );
					tempFile = new File( dir, test + '.css' );

					assertEquals( true, tempFile.exists(), tempFile + " exists?" );

					assertEquals( md5( CKRELEASER.io.readFile( correctFile ) ), md5( CKRELEASER.io.readFile( tempFile ) ),
							'Checking md5 of created file [' + dir.getName() + "/" + test + '.css]' );
				}
			}
			if ( foundCorrect )
				assertEquals( foundCorrect, foundCss, 'The number of created and correct css files must be equal in skin ' + dir.getName() );

			/**
			 * TODO: Loop through files and subdirectories in the source
			 * directory and make sure that all files != .css have been copied.
			 */
		}
	}

	function md5( s )
	{
		s = new java.lang.String( s );
		var m = java.security.MessageDigest.getInstance( "MD5" );
		m.update( s.getBytes(), 0, s.length() );
		return new java.math.BigInteger( 1, m.digest() ).toString( 16 );
	}

	function testSamples()
	{
		print( "\nTesting samples\n" );

		CKRELEASER.release.samples.source = '_assets/samples';
		CKRELEASER.release.samples.target = 'tmp/samples';
		CKRELEASER.release.samples.template = '_assets/samples/sample.html';

		var name = 'skins';
		var test, tempFile, correctFile;

		var samplesProcessor = new CKRELEASER.samplesProcessor();
		samplesProcessor.createSamples( '.', '.' );

		var dir = new File( CKRELEASER.release.samples.target );
		var dirList = dir.list();

		assertEquals( true, dirList.length > 0, dir + " not empty?" );

		for ( var j = 0 ; j < dirList.length ; j++ )
		{
			if ( dirList[j].indexOf( "correct.txt" ) != -1 )
			{
				test = dirList[j].replace( ".correct.txt", "" );

				correctFile = new File( dir, dirList[j] );

				if ( !correctFile.isDirectory() )
				{
					tempFile = new File( dir, test + '.html' );

					assertEquals( true, tempFile.exists(), tempFile + " exists?" );

					assertEquals( md5( CKRELEASER.io.readFile( correctFile ).replace( /(?:\r|\n)/g, "" ) ), md5( CKRELEASER.io.readFile(
							tempFile ).replace( /(?:\r|\n)/g, "" ) ), 'Checking md5 of created file [' + test + '.html]' );
				}
			}
		}
	}

	function testBom()
	{
		var file, extension;
		var dir = new File( 'tmp/bom' );

		CKRELEASER.io.copy( new File( '_assets/bom' ), dir );

		var children = dir.list();
		for ( var i = 0 ; i < children.length ; i++ )
		{
			file = new File( dir, children[i] );

			extension = CKRELEASER.io.getExtension( file.getName() );

			switch ( extension )
			{
				case "gif":
				case "jpg":
				case "jpeg":
				case "png":
				case "gz":
				case "zip":
					break;

				case "asp":
				case "js":
					CKRELEASER.io.setByteOrderMark( file, true );
					assertEquals( file.length(), 6 );
					break;

				default:
					CKRELEASER.io.setByteOrderMark( file, false );
					assertEquals( file.length(), 3 );
					break;
			}
		}
	}

	function testRemoveComments()
	{
		var tests = [ "/* comment \r\n\r\n something */\r\n\r\nword", "/* comment \r\n\r\n something */word",
				"/* comment \r\n\r\n something */\r\nword", "/* comment \r\n\r\n something */\n\nword",
				"/* comment \r\n\r\n something */\r\rword", "aa/* comment \r\n\r\n something */bb\n" ];
		var results = [ "\r\nword", "word", "word", "\nword", "\rword", "aabb\n" ];

		for ( var i = 0 ; i < tests.length ; i++ )
			assertEquals( results[i], CKRELEASER.tools.removeComments( tests[i] ) );
	}

	function testLineEndings()
	{
		print( "\nTesting line endings\n" );
		var testName, tempFile, correctFile, sampleFile;
		var name = "lineendings";
		var dir = new File( '_assets/lineendings' );
		var dirList = dir.list();

		for ( var i = 0 ; i < dirList.length ; i++ )
		{
			var f = new File( dir, dirList[i] );

			if ( dirList[i].indexOf( ".correct." ) == -1 )
				continue;

			testName = dirList[i].replace( ".correct", "" );

			sampleFile = new File( '_assets/' + name + '/' + testName );
			correctFile = new File( '_assets/' + name + '/' + dirList[i] );
			tempFile = new File( 'tmp/' + name + '/' + testName );

			CKRELEASER.io.copy( sampleFile, tempFile );
			CKRELEASER.tools.fixLineEndings( tempFile, true );

			assertEquals( CKRELEASER.io.readFile( correctFile ), CKRELEASER.io.readFile( tempFile ),
					'releaser.directives[' + testName + ']' );
		}
	}

	function listFiles( file )
	{
		var result = [];

		if ( file.isDirectory() )
		{
			var children = file.list();
			if ( !children.length )
			{
				result.push( file );
			}
			else
			{
				for ( var i = 0 ; i < children.length ; i++ )
				{
					result.push( listFiles( new File( file, children[i] ) ) );
				}
			}
		}
		else
		{
			result.push( file );
		}

		return result;
	}

	function testCopyFiles()
	{
		print( "\nTesting copying files...\n" );
		var releaser = new CKRELEASER.releaser();
		CKRELEASER.sourceDir = ".";
		CKRELEASER.releaseDir = ".";
		CKRELEASER.release.ignore = ['.svn'];
		CKRELEASER.release.copy = 
		[
			{
				source : '_assets/plugins',
				target : 'tmp/plugins',
				ignore : {
					sourcePackage : 'test.pack',
					files : 'packages[1].files'
				}
			}
		];
		releaser.copyFiles();
		var files = listFiles(new File(".", "tmp/plugins"));
		var validResult = [
			'./tmp/plugins/forms/dialogs/button.js',
			'./tmp/plugins/forms/dialogs/checkbox.js',
			'./tmp/plugins/forms/dialogs/form.js',
			'./tmp/plugins/forms/plugin.js',
			'./tmp/plugins/horizontalrule/plugin.js',
			'./tmp/plugins/specialchar/dialogs/specialchar.js'];

		assertEquals( files.length, 3, "Comparing plugins directories (same number of subfolders/files?)" );
		var areEqual = files.toString().replace(/\\/g, "/") == validResult.toString();
		assertEquals( true, areEqual, "Comparing plugins directories (are equal?)" );
	}
	prepareTempDirs();
	testDirectives();
	testSkins();
	testSamples();
	testRemoveComments();
	testBom();
	testLineEndings();
	testCopyFiles();

	print( '' );
	print( 'Finished: ' + passCount + ' passed / ' + failCount + ' failed' );

})();