/*******************************************************************************
 * Copyright (c) 2015, 2018 Willink Transformations 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:
 *     E.D.Willink - initial API and implementation
 *******************************************************************************/
package org.eclipse.qvtd.xtext.qvtimperative.tests;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.emf.common.EMFPlugin;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.examples.debug.vm.VMVirtualMachine;
import org.eclipse.ocl.examples.debug.vm.core.VMVariable;
import org.eclipse.ocl.examples.xtext.tests.TestFile;
import org.eclipse.ocl.examples.xtext.tests.TestProject;
import org.eclipse.ocl.examples.xtext.tests.TestUIUtil;
import org.eclipse.ocl.examples.xtext.tests.TestUtil;
import org.eclipse.ocl.pivot.Variable;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.ocl.pivot.utilities.OCL;
import org.eclipse.ocl.xtext.base.ui.model.BaseEditorCallback;
import org.eclipse.qvtd.debug.core.QVTiDebugTarget;
import org.eclipse.qvtd.debug.evaluator.QVTiVMRootEvaluationEnvironment;
import org.eclipse.qvtd.debug.launching.QVTiLaunchConstants;
import org.eclipse.qvtd.debug.vm.QVTiVMVirtualMachine;
import org.eclipse.qvtd.pivot.qvtimperative.ImperativeTransformation;
import org.eclipse.qvtd.pivot.qvtimperative.ImperativeTypedModel;
import org.eclipse.qvtd.pivot.qvtimperative.utilities.QVTimperativeUtil;
import org.eclipse.qvtd.xtext.qvtbase.tests.XtextTestCase;
import org.eclipse.qvtd.xtext.qvtimperative.ui.internal.QVTimperativeActivator;
import com.google.inject.Injector;

import junit.framework.TestCase;
import test.hsl.HSLTree.HSLTreePackage;
import test.hsv.HSVTree.HSVTreePackage;
import test.middle.HSV2HSL.HSV2HSLPackage;

/**
 * Tests that load a model and verify that there are no unresolved proxies as a result.
 */
public class QVTiDebuggerTests extends XtextTestCase
{
	public static @NonNull TestFile copyFile(@NonNull TestProject testProject, @NonNull URIConverter uriConverter, @NonNull URI sourceURI) throws IOException {
		InputStream inputStream = uriConverter.createInputStream(sourceURI);
		String lastSegment = sourceURI.lastSegment();
		assert lastSegment != null;
		return testProject.getOutputFile(lastSegment, inputStream);
	}

	private void checkPosition(@NonNull IThread vmThread, int lineNumber, int charStart, int charEnd) throws DebugException {
		IStackFrame topStackFrame = vmThread.getTopStackFrame();
		assertEquals("lineNumber", lineNumber, topStackFrame.getLineNumber());
		assertEquals("charStart", charStart, topStackFrame.getCharStart());
		assertEquals("charEnd", charEnd, topStackFrame.getCharEnd());
	}

	private void checkVariable(@NonNull IThread vmThread, @NonNull String name, @Nullable Object expectedValue) throws DebugException {
		IStackFrame topStackFrame = vmThread.getTopStackFrame();
		IVariable[] variables = topStackFrame.getVariables();
		if (variables != null){
			for (IVariable variable : variables) {
				if (name.equals(variable.getName()) && (variable instanceof VMVariable)) {
					Object valueObject = ((VMVariable)variable).getVmVar().valueObject;
					assertEquals(expectedValue, valueObject);
					return;
				}
			}
		}
		fail("Unknown variable '" + name + "'");
	}

	private void checkVariables(@NonNull IThread vmThread, String... names) throws DebugException {
		List<String> expectedNames = new ArrayList<String>();
		if (names != null){
			for (String name : names) {
				expectedNames.add(name);
			}
		}
		Collections.sort(expectedNames);
		IStackFrame topStackFrame = vmThread.getTopStackFrame();
		IVariable[] variables = topStackFrame.getVariables();
		List<String> actualNames = new ArrayList<String>();
		if (variables != null){
			for (IVariable variable : variables) {
				actualNames.add(variable.getName());
			}
		}
		Collections.sort(actualNames);
		assertEquals(expectedNames, actualNames);
	}

	protected ILaunchConfigurationWorkingCopy createLaunchConfiguration(@NonNull TestProject testProject, @NonNull String launchName,
			@NonNull TestFile txFile, @NonNull Map<String,String> newInKeys, @NonNull Map<String,String> newOutKeys) throws CoreException {
		ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
		ILaunchConfigurationType launchConfigurationType = launchManager.getLaunchConfigurationType(QVTiLaunchConstants.LAUNCH_CONFIGURATION_TYPE_ID);
		ILaunchConfigurationWorkingCopy launchConfiguration = launchConfigurationType.newInstance(testProject.getIProject(), launchName);
		launchConfiguration.setAttribute(QVTiLaunchConstants.TX_KEY, txFile.getURI().toString());
		//		launchConfiguration.setAttribute(QVTiLaunchConstants.OLD_IN_KEY, oldInKeys);
		launchConfiguration.setAttribute(QVTiLaunchConstants.NEW_IN_KEY, newInKeys);
		//		launchConfiguration.setAttribute(QVTiLaunchConstants.OLD_OUT_KEY, oldOutKeys);
		launchConfiguration.setAttribute(QVTiLaunchConstants.NEW_OUT_KEY, newOutKeys);
		launchConfiguration.setAttribute(QVTiLaunchConstants.INTERPRETED_KEY, true);
		launchConfiguration.setAttribute(QVTiLaunchConstants.TRACE_EVALUATION_KEY, false);
		return launchConfiguration;
	}

	@Override
	protected @NonNull String getProjectName() {
		return ClassUtil.nonNullState(getClass().getPackage().getName().replace('.', '/'));
	}

	public void testDebugger_Run_HSV2HSL() throws Exception {
		if (!EMFPlugin.IS_ECLIPSE_RUNNING) {
			return;
		}
		final @NonNull String inName = "hsl";
		final @NonNull String outName = "hsv";
		final @NonNull String middleName = "middle";
		TestUIUtil.closeIntro();
		TestUIUtil.enableSwitchToDebugPerspectivePreference();
		//
		OCL ocl = OCL.newInstance(OCL.CLASS_PATH);
		URIConverter uriConverter = ocl.getResourceSet().getURIConverter();
		TestProject testProject = getTestProject();
		TestFile txFile = copyFile(testProject, uriConverter, getModelsURI("HSV2HSL/HSV2HSL.qvti"));
		TestFile inFile = copyFile(testProject, uriConverter, getModelsURI("HSV2HSL/HSVNode.xmi"));
		copyFile(testProject, uriConverter, getModelsURI("HSV2HSL/HSVTree.ecore"));
		copyFile(testProject, uriConverter, getModelsURI("HSV2HSL/HSLTree.ecore"));
		copyFile(testProject, uriConverter, getModelsURI("HSV2HSL/HSV2HSL.ecore"));
		TestFile outFile = testProject.getOutputFile("HSLNode.xmi");
		TestFile middleFile = testProject.getOutputFile("HSV2HSLNode.xmi");
		Map<String,String> inMap = new HashMap<>();
		inMap.put(outName, inFile.getURI().toString());
		Map<String,String> outMap = new HashMap<>();
		outMap.put(inName, outFile.getURI().toString());
		outMap.put(middleName, middleFile.getURI().toString());
		ILaunchConfigurationWorkingCopy launchConfiguration = createLaunchConfiguration(testProject, "HSV2HSL", txFile, inMap, outMap);
		launchConfiguration.doSave();
		TestUIUtil.flushEvents();
		ILaunch launch = launchConfiguration.launch(ILaunchManager.RUN_MODE, null);
		assert launch != null;
		TestUIUtil.waitForLaunchToTerminate(launch);
		for (int i = 0; i < 10; i++) {
			testProject.getIProject().refreshLocal(IResource.DEPTH_INFINITE, null);
			if (outFile.getFile().exists()) {
				break;
			}
			TestUIUtil.wait(1000);
		}
		ResourceSet expectedResourceSet = new ResourceSetImpl();
		ocl.getProjectManager().initializeResourceSet(expectedResourceSet);
		Resource expectedResource = expectedResourceSet.getResource(getModelsURI("HSV2HSL/HSLNodeValidate.xmi"), true);
		assert expectedResource != null;
		ResourceSet actualResourceSet = new ResourceSetImpl();
		//		ocl.getProjectManager().initializeResourceSet(actualResourceSet);
		Resource actualResource = actualResourceSet.getResource(outFile.getURI(), true);
		assert actualResource != null;
		TestUtil.assertSameModel(expectedResource, actualResource);
		ocl.dispose();
	}

	public void testDebugger_Debug_HSV2HSL() throws Exception {
		if (!EMFPlugin.IS_ECLIPSE_RUNNING) {
			return;
		}
		// Debugger is interpreted and the HSV2HSL.qvti uses *.ecore not compiled models
		assert !EPackage.Registry.INSTANCE.containsKey(HSVTreePackage.eNS_URI);
		assert !EPackage.Registry.INSTANCE.containsKey(HSLTreePackage.eNS_URI);
		assert !EPackage.Registry.INSTANCE.containsKey(HSV2HSLPackage.eNS_URI);
		//		VMVirtualMachine.PRE_VISIT.setState(true);
		//		VMVirtualMachine.POST_VISIT.setState(true);
		//		VMVirtualMachine.VM_EVENT.setState(true);
		//		VMVirtualMachine.VM_REQUEST.setState(true);
		//		VMVirtualMachine.VM_RESPONSE.setState(true);
		final @NonNull String inName = "hsl";
		final @NonNull String outName = "hsv";
		final @NonNull String middleName = "middle";
		//
		TestUIUtil.closeIntro();
		TestUIUtil.enableSwitchToDebugPerspectivePreference();
		//
		Injector injector = QVTimperativeActivator.getInstance().getInjector(QVTimperativeActivator.ORG_ECLIPSE_QVTD_XTEXT_QVTIMPERATIVE_QVTIMPERATIVE);
		injector.getInstance(BaseEditorCallback.class).setDontAskForNatureAgain();
		OCL ocl = OCL.newInstance(OCL.CLASS_PATH);
		URIConverter uriConverter = ocl.getResourceSet().getURIConverter();
		TestProject testProject = getTestProject();
		TestFile txFile = copyFile(testProject, uriConverter, getModelsURI("HSV2HSL/HSV2HSL.qvti"));
		TestFile inFile = copyFile(testProject, uriConverter, getModelsURI("HSV2HSL/HSVNode.xmi"));
		copyFile(testProject, uriConverter, getModelsURI("HSV2HSL/HSVTree.ecore"));
		copyFile(testProject, uriConverter, getModelsURI("HSV2HSL/HSLTree.ecore"));
		copyFile(testProject, uriConverter, getModelsURI("HSV2HSL/HSV2HSL.ecore"));
		TestFile outFile = testProject.getOutputFile("HSLNode.xmi");
		TestFile middleFile = testProject.getOutputFile("HSV2HSLNode.xmi");
		Map<String,String> inMap = new HashMap<>();
		inMap.put(outName, inFile.getURI().toString());
		Map<String,String> outMap = new HashMap<>();
		outMap.put(inName, outFile.getURI().toString());
		outMap.put(middleName, middleFile.getURI().toString());

		ILaunchConfigurationWorkingCopy launchConfiguration = createLaunchConfiguration(testProject, "HSV2HSL", txFile, inMap, outMap);
		launchConfiguration.doSave();
		TestUIUtil.flushEvents();
		ILaunch launch = launchConfiguration.launch(ILaunchManager.DEBUG_MODE, null);
		assert launch != null;
		//
		/*		Map<String, Object> attributes = launch.getLaunchConfiguration().getAttributes();
		ExpressionInOCL asExpressionInOCL = (ExpressionInOCL) attributes.get(QVTiLaunchConstants.EXPRESSION_OBJECT);
		OperationCallExp asOperationCallExp = (OperationCallExp) asExpressionInOCL.getOwnedBody();
		PropertyCallExp asPropertyCallExpCallExp = (PropertyCallExp) asOperationCallExp.getOwnedSource();
		VariableExp asVariableExp = (VariableExp) asPropertyCallExpCallExp.getOwnedSource();
		NullLiteralExp asNullLiteralExp = (NullLiteralExp) asOperationCallExp.getOwnedArguments().get(0); */
		//
		QVTiDebugTarget debugTarget = (QVTiDebugTarget) launch.getDebugTarget();
		QVTiVMVirtualMachine vm = (QVTiVMVirtualMachine) debugTarget.getVM();
		QVTiVMRootEvaluationEnvironment vmRootEvaluationEnvironment = (QVTiVMRootEvaluationEnvironment) vm.getEvaluationEnv();
		assert vmRootEvaluationEnvironment != null;
		ImperativeTransformation asTransformation = (ImperativeTransformation) vmRootEvaluationEnvironment.getDebuggableElement();
		ImperativeTypedModel inTypedModel = QVTimperativeUtil.getOwnedTypedModel(asTransformation, inName);
		ImperativeTypedModel middleTypedModel = QVTimperativeUtil.getOwnedTypedModel(asTransformation, middleName);
		ImperativeTypedModel outTypedModel = QVTimperativeUtil.getOwnedTypedModel(asTransformation, outName);
		Variable asTransformationVariable = asTransformation.getOwnedContext();
		Variable asInVariable = inTypedModel.getOwnedContext();
		Variable asMiddleVariable = middleTypedModel.getOwnedContext();
		Variable asOutVariable = outTypedModel.getOwnedContext();
		assert (asTransformationVariable != null) && (asInVariable != null) && (asMiddleVariable != null) && (asOutVariable != null);

		IThread vmThread = debugTarget.getThreads()[0];
		assert vmThread != null;
		TestUIUtil.waitForSuspended(vmThread);
		TestUIUtil.waitForNotStepping(vmThread);
		//
		checkPosition(vmThread, 8, 448, 455);		// Values with OCL BaseLocationInFileProvider fix for Bug 495979
		checkVariables(vmThread, VMVirtualMachine.PC_NAME, "this", outName, inName, middleName);
		checkVariable(vmThread, VMVirtualMachine.PC_NAME, asTransformation);
		checkVariable(vmThread, "this", vmRootEvaluationEnvironment.getValueOf(asTransformationVariable));
		checkVariable(vmThread, outName, vmRootEvaluationEnvironment.getValueOf(asOutVariable));
		checkVariable(vmThread, inName, vmRootEvaluationEnvironment.getValueOf(asInVariable));
		checkVariable(vmThread, middleName, vmRootEvaluationEnvironment.getValueOf(asMiddleVariable));
		//
		vmThread.stepInto();
		TestUIUtil.waitForSuspended(vmThread);
		//
		checkPosition(vmThread, 21, 1067, 1075);
		checkVariables(vmThread, VMVirtualMachine.PC_NAME, "nodes");
		checkVariable(vmThread, VMVirtualMachine.PC_NAME, QVTimperativeUtil.getRootMapping(asTransformation));
		//
		vmThread.stepReturn();
		//		TestUIUtil.waitForTerminated(vmThread);
		boolean hasTerminated = false;
		for (int i = 0; i < 10; i++){
			TestUIUtil.flushEvents();
			Thread.sleep(100);
			if (vmThread.isTerminated()) {
				hasTerminated = true;
				break;
			}
		}
		if (!hasTerminated) {
			IStackFrame topStackFrame = vmThread.getTopStackFrame();
			IVariable[] variables = topStackFrame.getVariables();
			if (variables != null){
				for (IVariable variable : variables) {
					if (VMVirtualMachine.EXCEPTION_NAME.equals(variable.getName()) && (variable instanceof VMVariable)) {
						Object valueObject = ((VMVariable)variable).getVmVar().valueObject;
						throw (Exception)valueObject;
					}
				}
			}
			TestCase.fail("Failed to terminate");
		}
		assertEquals(0, vm.getExitCode());
		//
		TestUIUtil.flushEvents();
		ResourceSet expectedResourceSet = new ResourceSetImpl();
		ocl.getProjectManager().initializeResourceSet(expectedResourceSet);
		Resource expectedResource = expectedResourceSet.getResource(getModelsURI("HSV2HSL/HSLNodeValidate.xmi"), true);
		assert expectedResource != null;
		ResourceSet actualResourceSet = new ResourceSetImpl();
		//		ocl.getProjectManager().initializeResourceSet(expectedResourceSet);
		Resource actualResource = actualResourceSet.getResource(outFile.getURI(), true);
		assert actualResource != null;
		TestUtil.assertSameModel(expectedResource, actualResource);
		ocl.dispose();
	}
}
