/**
 * <copyright>
 *
 * Copyright (c) 2016 itemis 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:
 *     itemis - Initial API and implementation
 *
 * </copyright>
 */
package org.eclipse.sphinx.emf.mwe.dynamic.util;

import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.internal.core.SourceType;
import org.eclipse.osgi.util.NLS;
import org.eclipse.sphinx.emf.mwe.dynamic.internal.messages.Messages;
import org.eclipse.sphinx.emf.util.EcorePlatformUtil;
import org.eclipse.sphinx.emf.util.EcoreResourceUtil;
import org.eclipse.sphinx.emf.util.URIExtensions;
import org.eclipse.sphinx.jdt.util.JavaExtensions;

@SuppressWarnings("restriction")
public class WorkflowRunnerHelper {

	public String toWorkflowString(IType workflowType) {
		Assert.isNotNull(workflowType);

		if (workflowType.isBinary()) {
			return workflowType.getFullyQualifiedName();
		} else {
			return ((SourceType) workflowType).getPath().toString();
		}
	}

	public Object toWorkflowObject(String workflowString) throws ClassNotFoundException, FileNotFoundException {
		if (workflowString == null) {
			return null;
		}
		workflowString = workflowString.trim();

		Matcher matcher = JavaExtensions.CLASS_NAME_PATTERN.matcher(workflowString);
		if (matcher.find()) {
			// Workflow is a fully qualified Java class name
			try {
				return Class.forName(workflowString);
			} catch (ClassNotFoundException ex) {
				throw new ClassNotFoundException(NLS.bind(Messages.error_workflowClassNotFound, workflowString));
			}
		} else {
			// Workflow is assumed to be a workspace-relative path
			IPath workflowPath = new Path(workflowString);
			// TODO Perform more sophisticated error handling like below
			// TODO Move resulting logic to separate method and use it in toModelURIObject() as well
			// IWorkspace workspace = ResourcesPlugin.getWorkspace();
			// IStatus status = workspace.validateName(workflow, IResource.PROJECT);
			// if (status.isOK()) {
			// IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(workflow);
			// if (!project.exists()) {
			// setErrorMessage(NLS.bind(LauncherMessages.JavaMainTab_20, new String[] { workflow }));
			// return false;
			// }
			// if (!project.isOpen()) {
			// setErrorMessage(NLS.bind(LauncherMessages.JavaMainTab_21, new String[] { workflow }));
			// return false;
			// }
			// } else {
			// setErrorMessage(NLS.bind(Messages.error_illegalWorkflow, new String[] { status.getMessage() }));
			// return false;
			// }
			IFile workflowFile = ResourcesPlugin.getWorkspace().getRoot().getFile(workflowPath);
			if (!workflowFile.exists()) {
				IPath workflowLocation = ResourcesPlugin.getWorkspace().getRoot().getLocation().append(workflowPath);
				throw new FileNotFoundException(NLS.bind(Messages.error_workflowFileDoesNotExist, workflowLocation.toOSString()));
			}
			return workflowFile;
		}
	}

	public String toModelURIString(URI modelURI) {
		Assert.isNotNull(modelURI);

		return modelURI.toString();
	}

	public URI toModelURIObject(String modelURIString) throws FileNotFoundException {
		if (modelURIString == null) {
			return null;
		}
		modelURIString = modelURIString.trim();
		if (modelURIString.isEmpty()) {
			return null;
		}

		URI modelURI = URI.createURI(modelURIString);
		Path modelFilePath = new Path(modelURI.trimFragment().toString());
		URI absoluteModelFileURI = EcorePlatformUtil.createURI(modelFilePath.makeAbsolute());
		if (!EcoreResourceUtil.exists(absoluteModelFileURI)) {
			throw new FileNotFoundException(NLS.bind(Messages.error_modelResourceDoesNotExist, absoluteModelFileURI.toPlatformString(true)));
		}
		return absoluteModelFileURI.appendFragment(modelURI.fragment());
	}

	public Map<String, Object> toArgumentObjects(Map<String, String> argumentStrings) {
		Map<String, Object> arguments = new HashMap<String, Object>();
		if (argumentStrings != null) {
			for (String key : argumentStrings.keySet()) {
				String valueString = argumentStrings.get(key);
				Assert.isNotNull(valueString);
				valueString = valueString.trim();

				// Detect and convert boolean argument values
				Object value = null;
				if (Boolean.TRUE.toString().equalsIgnoreCase(valueString)) {
					value = Boolean.TRUE;
				} else if (Boolean.FALSE.toString().equalsIgnoreCase(valueString)) {
					value = Boolean.FALSE;
				}

				// Detect and convert URI argument values
				if (value == null) {
					URI valueURI = URI.createURI(valueString);
					if (key != null && key.contains(URI.class.getSimpleName())) {
						value = valueURI;
					}
					if (URIExtensions.isActual(valueURI)) {
						value = valueURI;
					}
				}

				// Take String argument values as is
				if (value == null) {
					value = valueString;
				}

				if (value != null) {
					arguments.put(key, value);
				}
			}
		}
		return arguments;
	}
}
