/**
 * File:    Converter.java
 * Created: 20.01.2009
 *
 *
/*******************************************************************************
 * Copyright (c) 2005-2011
 * University of Augsburg, Germany <www.ds-lab.org>
 *
 * 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:
 *    Christian Saad, Programming distributed Systems Lab, University of Augsburg 
 *    	- initial API and implementation
 *******************************************************************************/
/**
 * File:    Converter.java
 * Created: 21.01.2009
 *
 /*******************************************************************************
 * Copyright (c) 2005-2011
 * University of Augsburg, Germany <www.ds-lab.org>
 *
 * 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:
 *    Christian Saad, Programming distributed Systems Lab, University of Augsburg
 *
 *******************************************************************************/

package org.eclipse.jwt.converter;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.logging.Logger;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jwt.converter.internal.ConverterManager;
import org.eclipse.jwt.converter.internal.exception.UnsupportedVersionException;

/**
 * The class presents the interface for the JWT converter
 * 
 * @author Christian Saad (csaad@gmx.net), Programming distributed Systems Lab,
 *         University of Augsburg, Germany, www.ds-lab.org
 */
public class Converter
{

	/**
	 * A Logger.
	 */
	private static final Logger logger = Logger.getLogger(Converter.class.toString());

	/**
	 * Run in JUnit.
	 */
	private static boolean junit = false;


	/**
	 * Run in JUnit.
	 */
	public static void activateJUnitMode()
	{
		junit = true;
	}


	/**
	 * Read the version of the given workflow file.
	 * 
	 * @param modelFile
	 * @throws Exception 
	 */
	private static String readWEVersionFromFile(String modelFile) throws Exception
	{
		String fileVersion = "";

		FileInputStream inputStream = null;
		BufferedReader reader = null;
		String fileContents = "";
		try
		{
			inputStream = new FileInputStream(modelFile);
			StringBuilder sb = new StringBuilder();
			String line;

			reader = new BufferedReader(new InputStreamReader(inputStream));
			while ((line = reader.readLine()) != null)
				sb.append(line).append("\n");

			fileContents = sb.toString();

			// look for the fileversion tag
			int versionStringBegin = fileContents.indexOf("fileversion=\"")
					+ "fileversion=\"".length();
			int versionStringEnd = fileContents.indexOf("\"", versionStringBegin);

			if (versionStringBegin != -1 && versionStringEnd != -1
					&& versionStringBegin != versionStringEnd)
			{
				fileVersion = fileContents
						.substring(versionStringBegin, versionStringEnd);
			}
			reader.close();
		}
		catch (Exception e)
		{
			throw new Exception(PluginProperties.getString("convert_nosrcver_error"), e);
		}
		finally
		{
			try
			{
				reader.close();
				inputStream.close();
			}
			catch (Exception e)
			{
			}
		}

		return fileVersion;
	}


	/**
	 * Update the model using the converter.
	 * 
	 * @param modelFile
	 */
	public static void updateModel(URI modelFile, String targetVersion,
			boolean inAgilProMode) throws Exception
	{
		// the file path of the model file
		String filePath = modelFile.toFileString();

		if (filePath == null || !(new File(filePath)).exists())
		{
			URL url = new URL(modelFile.toString());
			filePath = FileLocator.resolve(url).toString().replace("file:", "");
		}

		// the source and target versions
		String sourceWEVersion = readWEVersionFromFile(filePath);
		String targetWEVersion = targetVersion;

		// the displayed versions
		String sourceWEVersionOfficial = sourceWEVersion;
		String targetWEVersionOfficial = targetWEVersion;

		// the displayed message
		String displayMessage = PluginProperties.getString("convert_sourcever_message")
				+ " \"" + sourceWEVersionOfficial + "\". "
				+ PluginProperties.getString("convert_targetver_message") + " \""
				+ targetWEVersionOfficial + "\". \n\n";

		// AgilPro: add 1 to the official (displayed) version number
		if (inAgilProMode)
		{
			String[] temp;
			temp = targetWEVersion.split("\\.");
			temp[0] = (new Integer((new Integer(temp[0])) + 1)).toString();
			targetWEVersionOfficial = temp[0] + "." + temp[1] + "." + temp[2]; //$NON-NLS-2$

			temp = sourceWEVersion.split("\\.");
			temp[0] = (new Integer((new Integer(temp[0])) + 1)).toString();
			sourceWEVersionOfficial = temp[0] + "." + temp[1] + "." + temp[2]; //$NON-NLS-2$
		}

		// show error if version could not be determined
		if (sourceWEVersion.equals(""))
		{
			logger.severe("could not read file version from workflow file " + filePath);

			if (!junit)
				MessageDialog.openError(null,
						PluginProperties.getString("convert_title"), displayMessage
								+ PluginProperties.getString("convert_nosrcver_error"));

			throw new Exception(
					PluginProperties
							.getString("could not determine the version of the source file"));
		}

		// exit if version of model file and current version are equal
		if (sourceWEVersion.equals(targetWEVersion))
		{
			return;
		}

		// info
		logger.info("converter: source model version " + sourceWEVersion
				+ ", target model version " + targetWEVersion);

		try
		{
			// convert to the current version
			ConverterManager.getInstance().convert(filePath, filePath, sourceWEVersion,
					targetWEVersion);
		}
		catch (UnsupportedVersionException e)
		{
			logger.severe("the file version " + sourceWEVersion + "of the workflow file "
					+ filePath + " is not supported");

			// version not supported error
			if (!junit)
				MessageDialog
						.openError(
								null,
								PluginProperties.getString("convert_title"),
								displayMessage
										+ PluginProperties
												.getString("convert_nosupport_message"));

			throw e;
		}
		catch (Exception e)
		{
			logger.severe("the update of the workflow file " + filePath
					+ " failed because of an unknown error");

			// unknown error
			if (!junit)
				MessageDialog.openError(null,
						PluginProperties.getString("convert_title"), displayMessage
								+ PluginProperties.getString("convert_fail_message"));

			e.printStackTrace();

			throw e;
		}

		logger.info("converter: the workflow file has been successfully converted to version "
				+ targetWEVersion);

		// success
		if (!junit)
			MessageDialog.openInformation(null,
					PluginProperties.getString("convert_title"), displayMessage
							+ PluginProperties.getString("convert_success_message"));

	}

}