/*******************************************************************************
* Copyright (c) 2007 IONA Technologies PLC
* 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:
*     IONA Technologies PLC - initial API and implementation
*******************************************************************************/
package org.eclipse.stp.sc.common.internal.model;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.stp.common.logging.LoggingProxy;
import org.eclipse.wst.server.core.IRuntime;
import org.eclipse.wst.server.core.IRuntimeType;
import org.eclipse.wst.server.core.IRuntimeWorkingCopy;
import org.eclipse.wst.server.core.IServerType;
import org.eclipse.wst.server.core.IServerWorkingCopy;
import org.eclipse.wst.server.core.ServerCore;


/**
 * wrap the wst runtime data model to use in STP
 * @author jma
 *
 */
public class RuntimeCore {

	public static final QualifiedName RUNTIMETYPE_PROPERTY = new QualifiedName("stp", "runtimeType");
    public static final QualifiedName RUNTIMEID_PROPERTY = new QualifiedName("stp", "runtimeId");
	
    public static final String JAXWS_MODULE_TYPE = "stp.jaxws.component";
    public static final String SCA_MODULE_TYPE = "stp.sca.component";

    /**
     * this is the system property used in unit test to set jax-ws kit location
     */
    public static final String JAXWS_KIT_TESTPROPERTY = "jaxws_kit_location";
    
    /**
     * this is the system property used in unit test to set sca kit location
     */
    public static final String SCA_KIT_TESTPROPERTY = "sca_kit_location";
    
	private static final LoggingProxy LOG = LoggingProxy.getlogger(RuntimeCore.class);
	

	public static IRuntime getRuntime(IProject project) {
		String runtimeId = getRuntimeID(project);
		return getRuntime(runtimeId);
	}
	
	public static IRuntime getRuntime(String runtimeId) {
		IRuntime[] runtimes = ServerCore.getRuntimes();
		if (runtimes != null) {
			for (IRuntime runtime : runtimes) {
				if (runtime.getId().equals(runtimeId)) {
					return runtime;
				}
			}
		}
		return null;
	}
		
	public static IPath getInstallPath(IProject project) {
		String runtimeId = getRuntimeID(project);
		return getInstallPath(runtimeId);
	}
	
	/**
	 * get the runtime installation directory according to runtime id
	 * @param runtimeId, the runtime id to lookup
	 * @return IPath, the install path
	 */
	public static IPath getInstallPath(String runtimeId) {
	
		IRuntime runtime = getRuntime(runtimeId);
		if (runtime != null) {
		    return runtime.getLocation();
		}
		//until here, we need to check if this method is called within unit test.
		//in that case, the kit location is passed from system property
		String property = System.getProperty(JAXWS_KIT_TESTPROPERTY);
		if (property != null) {
			return new Path(property);
		}
		
	    LOG.error("can't find the runtime with id:" + runtimeId);	
	    return null;	
	}

	public static String getRuntimeType(IProject project)  {
		try {
			return project.getPersistentProperty(RUNTIMETYPE_PROPERTY);
		} catch (CoreException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static void setRuntimeType(IProject project, String runtimeType) {
		try {
			project.setPersistentProperty(RUNTIMETYPE_PROPERTY, runtimeType);
		} catch (CoreException e) {
			e.printStackTrace();
		}
		
	}

	public static String getRuntimeID(IProject project) {
		try {
			return project.getPersistentProperty(RUNTIMEID_PROPERTY);
		} catch (CoreException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static void setRuntimeID(IProject project, String runtimeId) {
		try {
			project.setPersistentProperty(RUNTIMEID_PROPERTY, runtimeId);
		} catch (CoreException e) {
			e.printStackTrace();
		}
	}
	
	
	public static void createServer(String serverType, String serverId) {
		try{
			for (IServerType type : ServerCore.getServerTypes()) {
				if (type.equals(serverType)) {
					
					IServerWorkingCopy workingCopy = type.createServer(serverId, null, null);
					workingCopy.save(true, null);
					//Johnson, need to revist here. how to set server install dir. from runtime?
				}
			}
		} catch (Exception e) {
			LOG.error("error during create server.", e);
		}
		
	}
	
	/**
	 * create a runtime instance for input runtime type and location.
	 * @param runtimeType, the runtime type to create
	 * @param runtimeId, the ID of newly created runtime
	 * @param location, the installation directory for this runtime
	 * @return
	 */
	public static String creatRuntime(String runtimeType, String runtimeId, IPath location) {
		try {
			for (IRuntimeType type : ServerCore.getRuntimeTypes()) {
				if (type.getId().equals(runtimeType)) {
					IRuntimeWorkingCopy workingCopy = type.createRuntime(
							runtimeId, null);
					workingCopy.setLocation(location);
					IRuntime runtime = workingCopy.save(true, null);
					return runtime.getId();
				}
			}
		} catch (Exception e) {
			LOG.error("error during create runtime.", e);
		}
		return null;
	}
	
	public static String getRuntimeIdWithoutVersion(String id) {
		int index = id.lastIndexOf(".");
		if(index >= 0 ){
			return id.substring(0, index);
		}
		return "";
		
	}
}
