//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.library.tester.impl;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.epf.common.utils.XMLUtil;
import org.eclipse.epf.importing.services.PluginImportingService;
import org.eclipse.epf.library.edit.util.LibraryEditUtil;
import org.eclipse.epf.library.project.MethodLibraryProject;
import org.eclipse.epf.library.tester.LibraryDiffAnalyzor;
import org.eclipse.epf.library.tester.LibraryTestService;
import org.eclipse.epf.library.tester.iface.LibraryJunitTest;
import org.eclipse.epf.library.tester.iface.TCExeReply;
import org.eclipse.epf.library.tester.iface.TCExeReplyList;
import org.eclipse.epf.library.tester.iface.TestCommand;
import org.eclipse.epf.library.tester.iface.TestTracer;
import org.eclipse.epf.library.tester.impl.testcommands.TCCircularDependencyCheck;
import org.eclipse.epf.library.tester.impl.testcommands.TCCompareToGoldenFile;
import org.eclipse.epf.library.tester.impl.testcommands.TCCompareToLibrary;
import org.eclipse.epf.library.tester.impl.testcommands.TCCopyLibrary;
import org.eclipse.epf.library.tester.impl.testcommands.TCEditMethodElement;
import org.eclipse.epf.library.tester.impl.testcommands.TCExeReplyImpl;
import org.eclipse.epf.library.tester.impl.testcommands.TCExeReplyListImpl;
import org.eclipse.epf.library.tester.impl.testcommands.TCExportConfiguration;
import org.eclipse.epf.library.tester.impl.testcommands.TCExportPlugins;
import org.eclipse.epf.library.tester.impl.testcommands.TCExportXml;
import org.eclipse.epf.library.tester.impl.testcommands.TCImportConfiguration;
import org.eclipse.epf.library.tester.impl.testcommands.TCImportPlugins;
import org.eclipse.epf.library.tester.impl.testcommands.TCImportXml;
import org.eclipse.epf.library.tester.impl.testcommands.TCNewMethodConfiguration;
import org.eclipse.epf.library.tester.impl.testcommands.TCNewMethodElement;
import org.eclipse.epf.library.tester.impl.testcommands.TCNewMethodPlugin;
import org.eclipse.epf.library.tester.impl.testcommands.TCOpenLibrary;
import org.eclipse.epf.library.tester.impl.testcommands.TCOutputMethodElement;
import org.eclipse.epf.library.tests.LibraryTestHelper;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.library.xmi.XMILibraryUtil;
import org.eclipse.epf.uma.CapabilityPattern;
import org.eclipse.epf.uma.ContentPackage;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.ProcessComponent;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * Used in JUnit tests 
 * 
 * @author Weiping Lu
 * @since 1.0
 * 
 */
public class TestCommandMgr implements TestTracer {	
	
	//All the tags will be formally specified and read from
	//a schema later.	
	private static String TCCopyLibrary = "CopyLibrary";
	private static String TCOpenLibrary = "OpenLibrary";
	private static String TCExportPlugins = "ExportPlugins";
	private static String TCImportPlugins = "ImportPlugins";	
	private static String TCExportConfiguration = "ExportConfiguration";
	private static String TCImportConfiguration = "ImportConfiguration";
	private static String TCExportXml = "ExportXml";
	private static String TCImportXml = "ImportXml";
	private static String TCCompareToLibrary = "CompareToLibrary";
	private static String TCCompareToGoldenFile = "CompareToGoldenFile";
	private static String TCNewMethodPlugin = "NewMethodPlugin";
	private static String TCNewMethodConfiguration = "NewMethodConfiguration";
	private static String TCNewMethodElement = "NewMethodElement";
	private static String TCEditMethodElement = "EditMethodElement";
	private static String TCCircularDependencyCheck = "CircularDependencyCheck";
	private static String TCEnd = "End";
	
	private static String TCEditPlugin="EditPlugin";
	private static String TCEditConfiguration="EditConfiguration";
	private static String TCEditContentPackage="EditContentPackage";
	
	public static String TCOutputLibrary="OutputLibrary";
	public static String TCOutputPlugin="OutputPlugin";
	public static String TCOutputConfiguration="OutputConfiguration";
	public static String TCOutputMethodElement="OutputMethodElement";
		
	private boolean trace = false;
	private boolean removeFiles = true;
	
	private File testRootSource;
	private File testRootWorking;
	private File currTestDir;
	private String outputPath;
	private Document outputDocument;
	private PrintStream testRootOut;
	private PrintStream currTestOut;
	private int executedTestCount = 0;	
		
	private static LibraryTestService service = LibraryTestService.getInstance();
	private File testFile;
	private List testCommandList = new ArrayList();
	private LibraryJunitTest junitTestCase;
	
	private MethodLibrary currentBaseLib;
	private Map allLibs = new LinkedHashMap();
	private Map allExports = new LinkedHashMap();	
	
	private static Map tcClassMap = new HashMap();
	private static Map tcTagNameMap = new HashMap();
	
	private PrintStream logPS = System.out;
	
	static {
		addToTcClassMap(TCCopyLibrary, TCCopyLibrary.class);
		addToTcClassMap(TCOpenLibrary, TCOpenLibrary.class);
		addToTcClassMap(TCExportPlugins, TCExportPlugins.class);
		addToTcClassMap(TCImportPlugins, TCImportPlugins.class);		
		addToTcClassMap(TCExportConfiguration, TCExportConfiguration.class);
		addToTcClassMap(TCImportConfiguration, TCImportConfiguration.class);
		addToTcClassMap(TCExportXml, TCExportXml.class);
		addToTcClassMap(TCImportXml, TCImportXml.class);		
		addToTcClassMap(TCCompareToLibrary, TCCompareToLibrary.class);
		addToTcClassMap(TCCompareToGoldenFile, TCCompareToGoldenFile.class);
		
		addToTcClassMap(TCNewMethodPlugin, TCNewMethodPlugin.class);
		addToTcClassMap(TCNewMethodConfiguration, TCNewMethodConfiguration.class);		
		addToTcClassMap(TCNewMethodElement, TCNewMethodElement.class);
		addToTcClassMap(TCEditMethodElement, TCEditMethodElement.class);
		
		addToTcClassMap(TCEditPlugin, TCEditMethodElement.class);
		addToTcClassMap(TCEditConfiguration, TCEditMethodElement.class);
		addToTcClassMap(TCEditContentPackage, TCEditMethodElement.class);
		
		addToTcClassMap(TCOutputLibrary, TCOutputMethodElement.class);
		addToTcClassMap(TCOutputPlugin, TCOutputMethodElement.class);
		addToTcClassMap(TCOutputConfiguration, TCOutputMethodElement.class);
		addToTcClassMap(TCOutputMethodElement, TCOutputMethodElement.class);
		addToTcClassMap(TCCircularDependencyCheck, TCCircularDependencyCheck.class);
	}
	
	private static void addToTcClassMap(String elementName, Class cls) {
		Object instance = null;
		try {
			instance = cls.newInstance();
		} catch (Exception e){
			e.printStackTrace();
		}
		if (instance instanceof TestCommand) {
			tcClassMap.put(elementName, instance);
			tcTagNameMap.put(cls, elementName);
		}		
	}

	public TestCommandMgr(boolean trace) {
		if (trace) {
			this.trace = trace;
			this.removeFiles = !trace;
		}
		
		LibraryEditUtil.getInstance().setJunitTest(true);
	}	
	
	public String getTagName(TestCommand tcInstance) {
		return (String) tcTagNameMap.get(tcInstance.getClass());
	}
	
	public void setTestRootSource(File dirFile) {
		testRootSource = dirFile;
	}
	
	public void setTestRootWorking(File dirFile) {
		boolean needToCreateOutputFile = testRootWorking == null ||
								! testRootWorking.equals(dirFile);
		
		testRootWorking = dirFile;
		
		if (trace && needToCreateOutputFile) {
			try {
				if (! testRootWorking.exists()) {					
					if (! mkDir(testRootWorking)) {
						return;
					}
				}
				if (testRootOut != null) {
					testRootOut.close();
				}
				String path = testRootWorking.getAbsolutePath() + File.separator + "traces.out";
				testRootOut = new PrintStream(new FileOutputStream(path));

			} catch (Exception e) {	
				e.printStackTrace();
			}
		}
	}
	
	private boolean mkDir(File file) {
		File pFile = file.getParentFile();		
		if (! pFile.exists()) {					
			if (! mkDir(pFile)) {
				return false;
			}
		}
		return file.mkdir();
	}
	
	public void openCurrTestDir(File dirFile) {
		currTestDir = dirFile;
		
		try {
			if (! currTestDir.exists()) {
				currTestDir.mkdir();
			}
			String path = currTestDir.getAbsolutePath() + File.separator;
			if (trace) {
				currTestOut = new PrintStream(new FileOutputStream(path + "trace.out"));
			}
			outputPath = path + "output.xml";
		} catch (Exception e) {	
			e.printStackTrace();
		}
	}
	
	public void closeCurrTestDir() {
		closeLibrary(getCurrentBaseLib());
		if (currTestOut != null) {
			currTestOut.close();
			currTestOut = null;
		}
		clearOutputDocument();
		allLibs = new LinkedHashMap();
		allExports = new LinkedHashMap();
		closeFolder(currTestDir);
	}
	
	public void doneWithAllTests(File topCleanUpFolder) {
		closeAllExportProjects();
		if (testRootOut != null) {
			testRootOut.close();
		}
		closeFolder(topCleanUpFolder);
	}
	
	public File getCurrTestDir() {
		return currTestDir;
	}
	
	public void setTest(File testFile) {
		this.testFile = testFile;		
	}	
	
	public File getTestFile() {
		return testFile;		
	}	
	
	
	public LibraryTestService getService() {
		return service;
	}
	
	public TCExeReplyList execute() {
		trace("Begin executing: " + testFile);

		TCExeReplyList result = null;
		boolean loaded = false;
		Exception loadException = null;
		try {
			loaded = loadTest();			
		} catch (Exception e) {
			loadException = e;
			e.printStackTrace();
		}
		
		if (loaded) {			
			String path = testRootWorking.getAbsolutePath() + File.separator + testFile.getName() + ".dir";
			openCurrTestDir(new File (path));
			result = executeCommands();		
			closeCurrTestDir();
		} else {
			result = new TCExeReplyListImpl();
			if (loadException != null) {
				String msg = "Test load failed: " + loadException.getMessage();
				((TCExeReplyListImpl) result).add(new TCExeReplyImpl(msg, false));
				trace(msg);
			} else {			
				trace("Test disabled");
			}
		}
		
		trace("End executing  : " + testFile);
		return result;
	}
	
	private boolean loadTest() throws Exception {
		testCommandList.clear();
		Document document = XMLUtil.loadXml(testFile);	
		Element root = document.getDocumentElement();
		if (root.getAttribute(TestCommand.AT_Disable).equals("true")) {
			return false;				
		}
		boolean verbose = root.getAttribute(TestCommand.AT_Verbose).equalsIgnoreCase("true");
		NodeList nodes = root.getChildNodes();
		int sz = nodes == null ? 0 : nodes.getLength();
		for (int i=0; i<sz; i++) {
			Node node = nodes.item(i);
			if (node instanceof Element) {
				Element element = (Element) node;
				if (verbose) {
					element.setAttribute(TestCommand.AT_Verbose, "true");
				}
				if (element.getTagName().equalsIgnoreCase(TCEnd)) {
					break;
				}
				addCommand(node);
			}
		}			
		return true;
	}
	
	public TCExeReplyList executeCommands() {
		TCExeReplyListImpl result = new TCExeReplyListImpl();
		for (int i=0; i<testCommandList.size(); i++) {
			TestCommandImpl command = (TestCommandImpl) testCommandList.get(i);
			TCExeReply reply = null;
			try {
				reply = command.execute();
			} catch (Exception e) {
				e.printStackTrace();
				reply = new TCExeReplyImpl(e.getMessage(), false);
			}
			if (reply != null) {
				result.add(reply);
				if (!reply.passing()) {
					log("\nThe following command is not passing: \n" +  command.getElement() + "\n");
				}
			}
		}			
		
		String line = testFile.getName() + " is ";
		String dirStr = "testRootSource: " + testRootSource 
						+ ", testRootWorking: " + testRootWorking;
		if (result.passing()) {
			line += "passing. " + dirStr;
		} else {
			line += "failing! " + dirStr;
		}
		result.setSummaryReply(line);
		return result;
	}
	
	public void trace(String line) {
		if (testRootOut != null) {
			testRootOut.println(line);
		}
		
		if (currTestOut != null) {
			currTestOut.println(line);
		}
	}
	
	private void addCommand(Node node) {
		if ( !(node instanceof Element)) {
			return;
		}
		Element element = (Element) node;
		if (! element.getAttribute(TestCommand.AT_Disable).equals("true")) {
			TestCommand command = newTestCommand(element.getTagName());
			if (command != null) {
				command.parse(element);
				testCommandList.add(command);
			}
		}
	}	
	
	private TestCommand newTestCommand(String comandName) {
		Object obj = tcClassMap.get(comandName);
		return obj == null ? null : newTestCommand(obj.getClass());
	}
	
	public TestCommand newTestCommand(Class cls) {
		TestCommand ret = null;
		try {
			ret = (TestCommand) cls.newInstance();
			((TestCommandImpl) ret).setOwner(this);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return ret;
	}
		
	private MethodLibrary loadBaseLib(String name, boolean ifNewThenBuildDeafaultLib) {
		if (currentBaseLib != null) {
			File file = new File(currentBaseLib.eResource().getURI().toFileString()).getParentFile();
			if (file.getName().equals(name)) {			
				return currentBaseLib;
			}
		}
		
		if (allExports.containsKey(name)) {
			throw new UnsupportedOperationException();
		}
		
		service.closeLibrary(currentBaseLib);
		
		currentBaseLib = null;
		String libPath = (String) allLibs.get(name);
		if (libPath == null) {
			libPath = currTestDir.getAbsolutePath() + File.separator + name;	
			try {
				currentBaseLib = copyFromTestLibs(libPath, name) ?  
								XMILibraryUtil.openMethodLibrary(libPath) : null;
			} catch (Exception e) {				
			}
			if (currentBaseLib == null) {
				currentBaseLib = service.createLibrary(libPath, name);
				if (ifNewThenBuildDeafaultLib) {
					buildDefaultLibrary();
				}
				trace("Base lib \"" + name + "\" is created.");
			} else {
				trace("Base lib \"" + name + "\" is copied from testLibs and laoded.");
			}
			allLibs.put(name, libPath);
		} else {
			try {
				currentBaseLib = XMILibraryUtil.openMethodLibrary(libPath);
				trace("Base lib \"" + name + "\" is loaded.");
			} catch (Exception e) {			
				trace(e.getMessage());
			}
		}
		return currentBaseLib;
	}			
	
	public MethodLibrary loadNonBaseLib(String name) {
		String libPath = (String) allLibs.get(name);
		if (libPath == null) {
			throw new UnsupportedOperationException();
		}
		return service.loadLibrary(libPath);
	}			
	
	public MethodLibrary getCurrentBaseLib() {
		return currentBaseLib;
	}
	
	public void setCurrentBaseLib(MethodLibrary lib) {
		currentBaseLib = lib;
	}
	
	public MethodLibrary loadBaseLib(String name) {
		return loadBaseLib(name, false);
	}
	
	public MethodLibrary loadBaseLibOrBuildBaseWithDefault(String name) {
		return loadBaseLib(name, true);
	}
	
	public File getImportFile(String importFolderName) {
		File file = (File) allExports.get(importFolderName);
		if (file == null) {
			file = new File(testRootSource.getAbsolutePath() + File.separator + importFolderName);
			if (file.exists() && file.isDirectory()) {
				return file;
			}
			return null;
		}
		return file;
	}
	
	public File registerExportDestination(String name, boolean isXML) {
		if (allLibs.containsKey(name)) {
			throw new UnsupportedOperationException();
		}
		File file = (File) allExports.get(name);
		if (file == null) {
			String path = currTestDir.getAbsolutePath() + File.separator + name;
			if (isXML) {
				path += File.separator + name + ".xml";
			}
			file =  new File(path);
			allExports.put(name, file);
		}
		return file;
	}	
	
	public void closeLibrary(MethodLibrary lib) {
		service.closeLibrary(lib);
		setCurrentBaseLib(null);
	}
	
	public void closeFolder(File folder) {
		if (removeFiles) {
			service.deleteFolder(folder);
		}
	}
	
	public int incExecutedTestCount() {
		return ++executedTestCount;
	}
	
	public void closeAllExportProjects() {
		for (Iterator it = allExports.values().iterator(); it.hasNext();) {
			File file = (File) it.next();
			try {
				MethodLibraryProject.closeProject(file.getAbsolutePath(), new NullProgressMonitor());
			} catch (Throwable e){					
			}
		}	
	}	
	
	public boolean compareLibs(MethodLibrary lib1,  MethodLibrary lib2) {
		return compareLibs(lib1, lib2, false);
	}
	
	public boolean compareLibs(MethodLibrary lib1,  MethodLibrary lib2, boolean useNameAs2ndId) {
		LibraryDiffAnalyzor analyzor = new LibraryDiffAnalyzor(this, lib1, lib2);
		analyzor.setGreedy(trace);
		analyzor.setUseNameAs2ndId(useNameAs2ndId);
		return analyzor.compare();
	}
	
	public boolean compareLibs(MethodLibrary lib1,  MethodLibrary lib2, int diffCount, int elemComparedCount, boolean useNameAs2ndId) {
		if (diffCount == 0 && elemComparedCount == 0) {
			return compareLibs(lib1, lib2, useNameAs2ndId);
		}
		LibraryDiffAnalyzor analyzor = new LibraryDiffAnalyzor(this, lib1, lib2);
		analyzor.setGreedy(true);
		analyzor.setUseNameAs2ndId(useNameAs2ndId);
		analyzor.compare();
		return 	analyzor.getDiffCount() == diffCount &&
			 	analyzor.getElemComparedCount() == elemComparedCount;
	}
	
	public void buildDefaultLibrary() {		
		trace("buildDefaultLibrary ->");
		
		MethodPlugin plugin = LibraryTestHelper.createMethodPlugin("Plug_A");
		ContentPackage pkg = LibraryTestHelper.createContentPackage(plugin, "p1");		
		MethodConfiguration config = LibraryTestHelper.createConfiguration("Config_A");
		CapabilityPattern cp1 = LibraryTestHelper.createCapabilityPattern(plugin, "CP1", config);
		CapabilityPattern cp2 = LibraryTestHelper.createCapabilityPattern(plugin, "CP2", config);		
		LibraryTestHelper.setContributes(cp2, cp1);
		
		// update the configuration
		config.getMethodPluginSelection().add(plugin);
		config.getMethodPackageSelection().add(pkg);
		config.getMethodPackageSelection().add((ProcessComponent)cp1.eContainer());
		config.getMethodPackageSelection().add((ProcessComponent)cp2.eContainer());
		
		LibraryUtil.validateMethodConfiguration(config);	
		
		final String cp1_text = "cp1 main desc";
		final String cp2_text = "cp2 main desc";
			
		cp1.getPresentation().setMainDescription(cp1_text);
		cp2.getPresentation().setMainDescription(cp2_text);

		trace("buildDefaultLibrary <-");

	}
	
	public boolean copyFromTestLibs(String libPath, String relLibNamePath) {
		File source = new File(testRootSource.getAbsolutePath() + File.separator + relLibNamePath);
		String libName = source.getName();
		File libList[] = source.getParentFile().listFiles();
		for (int i=0; i<libList.length; i++) {
			File file = libList[i];
			if (libName.equals(file.getName())) {
				File target = new File(libPath);
				PluginImportingService.copyDir(source, target);
				allLibs.put(libName, libPath);
				return true;
			}
		}
		return false;
	}
	
	public Document getOutputDocument() {
		if (outputDocument == null) {			
			try {
				outputDocument = XMLUtil.createDocument();
		        Element root = outputDocument.createElement("TesterOutput");
		        outputDocument.appendChild(root);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return outputDocument;
	}
	
	private void clearOutputDocument() {
		outputDocument = null;
	}
	
	public String getOutputPath() {
		return outputPath;
	}
	
	public void log(String line) {
		logPS.println(line);
	}
	
}
