/*******************************************************************************
 * Copyright (c) 2005, 2007 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 API and implementation
 *******************************************************************************/
package org.eclipse.jst.jee.util.internal;

import java.io.IOException;
import java.io.InputStream;

import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.J2EEVersionConstants;
import org.xml.sax.InputSource;

/**
 * A Utility for quickly determining the type and version of a Java EE
 * deployment descriptor.
 * 
 * @author jasholl
 * 
 */
public class JavaEEQuickPeek implements J2EEVersionConstants {

	private static final int UNSET = -2;

	private XMLRootHandler handler = null;

	public JavaEEQuickPeek(int type, int version) {
		this(type, version, UNSET);
	}

	public JavaEEQuickPeek(int type, int version, int javaEEVersion) {
		if (type == UNKNOWN) {
			throw new RuntimeException("type must not be UNKNOWN");
		} else if (version == UNKNOWN) {
			throw new RuntimeException("version must not be UNKNONW");
		} else if (javaEEVersion == UNKNOWN) {
			throw new RuntimeException("javaEEVersion must not be UNKNONW");
		}
		this.type = type;
		this.version = version;
		this.javaEEVersion = javaEEVersion;
	}

	public JavaEEQuickPeek(InputStream in) {
		if (in != null) {
			try {
				InputSource inputSource = new InputSource(in);
				handler = new XMLRootHandler();
				handler.parseContents(inputSource);
			} catch (Exception ex) {
				// ignore
			} finally {
				try {
					if (in != null) {
						in.reset();
					}
				} catch (IOException ex) {
					// ignore
				}
			}
		} else {
			version = UNKNOWN;
			javaEEVersion = UNKNOWN;
			type = UNKNOWN;
		}
	}

	private int version = UNSET;

	private int javaEEVersion = UNSET;

	private int type = UNSET;

	/**
	 * Returns the deployment descriptor type as defined by one of
	 * {@link J2EEVersionConstants#UNKNOWN},
	 * {@link J2EEVersionConstants#APPLICATION_CLIENT_TYPE},
	 * {@link J2EEVersionConstants#APPLICATION_TYPE},
	 * {@link J2EEVersionConstants#EJB_TYPE},
	 * {@link J2EEVersionConstants#CONNECTOR_TYPE},
	 * {@link J2EEVersionConstants#WEB_TYPE},
	 * {@link J2EEVersionConstants#WEBSERVICES_TYPE}
	 * 
	 * @return
	 */
	public int getType() {
		if (type == UNSET) {
			String rootName = handler.getRootName();
			if (rootName == null) {
				type = UNKNOWN;
			} else if (rootName.equals(J2EEConstants.APP_CLIENT_DOCTYPE)) {
				type = APPLICATION_CLIENT_TYPE;
			} else if (rootName.equals(J2EEConstants.APPLICATION_DOCTYPE)) {
				type = APPLICATION_TYPE;
			} else if (rootName.equals(J2EEConstants.EJBJAR_DOCTYPE)) {
				type = EJB_TYPE;
			} else if (rootName.equals(J2EEConstants.CONNECTOR_DOCTYPE)) {
				type = CONNECTOR_TYPE;
			} else if (rootName.equals(J2EEConstants.WEBAPP_DOCTYPE)) {
				type = WEB_TYPE;
			} else if (rootName.equals(J2EEConstants.WEB_SERVICES_DOCTYPE)) {
				type = WEBSERVICES_TYPE;
			}else {
				type = UNKNOWN;
			}
		}
		return type;
	}

	public static String normalizeSchemaLocation(String schemaLocation){
		if(schemaLocation == null){
			return null;
		}
		char [] oldChars = schemaLocation.toCharArray();
		char [] newChars = new char[oldChars.length];
		int newCharIndex = 0;
		boolean onWhiteSpace = true;
		boolean afterWhiteSpace = false;
		for(int oldCharIndex=0; oldCharIndex<oldChars.length; oldCharIndex++){
			afterWhiteSpace = onWhiteSpace;
			onWhiteSpace = Character.isWhitespace(oldChars[oldCharIndex]);
			boolean shouldSkip = onWhiteSpace && afterWhiteSpace;
			if(!shouldSkip){
				newChars[newCharIndex++] = onWhiteSpace ? ' ' : oldChars[oldCharIndex];
			}
			boolean atEnd = ((oldCharIndex + 1) == oldChars.length);
			if(atEnd && onWhiteSpace){
				while(newCharIndex > 0  && newChars[newCharIndex-1] == ' '){
					newCharIndex --;
				}
			}
		}
		if(newChars != null){
			return new String(newChars, 0, newCharIndex);
		} else {
			return schemaLocation;
		}
	}
	
	/**
	 * Returns the module version for this deployment descriptor type. For
	 * example, if this is a EJB 3.0 deployment descriptor, this returns the
	 * constant for 3.0 as defined bye {@link J2EEVersionConstants}
	 * 
	 * @return
	 */
	public int getVersion() {
		if (version == UNSET) {
			String publicID = handler.getDtdPublicID();
			String systemID = handler.getDtdSystemID();
			String schemaName = null;
			if (publicID == null || systemID == null) {
				if (handler.getRootAttributes() != null) {
					schemaName = normalizeSchemaLocation(handler.getRootAttributes().getValue("xsi:schemaLocation")); //$NON-NLS-1$
				}
				if (schemaName == null) {
					version = UNKNOWN;
					return version;
				}
			}
			switch (getType()) {
			case APPLICATION_CLIENT_TYPE:
				if (publicID != null && systemID != null) {
					if (publicID.equals(J2EEConstants.APP_CLIENT_PUBLICID_1_3)
							&& (systemID.equals(J2EEConstants.APP_CLIENT_SYSTEMID_1_3) || systemID.equals(J2EEConstants.APP_CLIENT_ALT_SYSTEMID_1_3))) {
						version = J2EEVersionConstants.J2EE_1_3_ID;
					} else if (publicID.equals(J2EEConstants.APP_CLIENT_PUBLICID_1_2)
							&& (systemID.equals(J2EEConstants.APP_CLIENT_SYSTEMID_1_2) || systemID.equals(J2EEConstants.APP_CLIENT_ALT_SYSTEMID_1_2))) {
						version = J2EEVersionConstants.J2EE_1_2_ID;
					}
				} else if (schemaName != null) {
					if (schemaName.equals(J2EEConstants.APP_CLIENT_SCHEMA_1_4)) {
						version = J2EEVersionConstants.J2EE_1_4_ID;
					} else if (schemaName.equals(J2EEConstants.APP_CLIENT_SCHEMA_5)) {
						version = J2EEVersionConstants.JEE_5_0_ID;
					}
				}
				break;
			case APPLICATION_TYPE:
				if (publicID != null && systemID != null) {
					if (publicID.equals(J2EEConstants.APPLICATION_PUBLICID_1_3)
							&& (systemID.equals(J2EEConstants.APPLICATION_SYSTEMID_1_3) || systemID.equals(J2EEConstants.APPLICATION_ALT_SYSTEMID_1_3))) {
						version = J2EEVersionConstants.J2EE_1_3_ID;
					} else if (publicID.equals(J2EEConstants.APPLICATION_PUBLICID_1_2)
							&& (systemID.equals(J2EEConstants.APPLICATION_SYSTEMID_1_2) || systemID.equals(J2EEConstants.APPLICATION_ALT_SYSTEMID_1_2))) {
						version = J2EEVersionConstants.J2EE_1_2_ID;
					}
				} else if (schemaName != null) {
					if (schemaName.equals(J2EEConstants.APPLICATION_SCHEMA_1_4)) {
						version = J2EEVersionConstants.J2EE_1_4_ID;
					} else if (schemaName.equals(J2EEConstants.APPLICATION_SCHEMA_5)) {
						version = J2EEVersionConstants.JEE_5_0_ID;
					}
				}
				break;
			case EJB_TYPE:
				if (publicID != null && systemID != null) {
					if (publicID.equals(J2EEConstants.EJBJAR_PUBLICID_2_0) && (systemID.equals(J2EEConstants.EJBJAR_SYSTEMID_2_0) || systemID.equals(J2EEConstants.EJBJAR_ALT_SYSTEMID_2_0))) {
						version = J2EEVersionConstants.EJB_2_0_ID;
					} else if (publicID.equals(J2EEConstants.EJBJAR_PUBLICID_1_1) && (systemID.equals(J2EEConstants.EJBJAR_SYSTEMID_1_1) || systemID.equals(J2EEConstants.EJBJAR_ALT_SYSTEMID_1_1))) {
						version = J2EEVersionConstants.EJB_1_1_ID;
					}
				} else if (schemaName != null) {
					if (schemaName.equals(J2EEConstants.EJBJAR_SCHEMA_2_1)) {
						version = J2EEVersionConstants.EJB_2_1_ID;
					} else if (schemaName.equals(J2EEConstants.EJBJAR_SCHEMA_3_0)) {
						version = J2EEVersionConstants.EJB_3_0_ID;
					}
				}
				break;
			case CONNECTOR_TYPE:
				if (publicID != null && systemID != null) {
					if (publicID.equals(J2EEConstants.CONNECTOR_PUBLICID_1_0) && (systemID.equals(J2EEConstants.CONNECTOR_SYSTEMID_1_0) || systemID.equals(J2EEConstants.CONNECTOR_ALT_SYSTEMID_1_0))) {
						version = J2EEVersionConstants.JCA_1_0_ID;
					}
				} else if (schemaName != null) {
					if (schemaName.equals(J2EEConstants.CONNECTOR_SCHEMA_1_5)) {
						version = J2EEVersionConstants.JCA_1_5_ID;
					}
				}
				break;
			case WEB_TYPE:
				if (publicID != null && systemID != null) {
					if (publicID.equals(J2EEConstants.WEBAPP_PUBLICID_2_3) && (systemID.equals(J2EEConstants.WEBAPP_SYSTEMID_2_3) || systemID.equals(J2EEConstants.WEBAPP_ALT_SYSTEMID_2_3))) {
						version = J2EEVersionConstants.WEB_2_3_ID;
					} else if (publicID.equals(J2EEConstants.WEBAPP_PUBLICID_2_2) && (systemID.equals(J2EEConstants.WEBAPP_SYSTEMID_2_2) || systemID.equals(J2EEConstants.WEBAPP_ALT_SYSTEMID_2_2))) {
						version = J2EEVersionConstants.WEB_2_2_ID;
					}
				} else if (schemaName != null) {
					if (schemaName.equals(J2EEConstants.WEBAPP_SCHEMA_2_4)) {
						version = J2EEVersionConstants.WEB_2_4_ID;
					} else if (schemaName.equals(J2EEConstants.WEBAPP_SCHEMA_2_5)) {
						version = J2EEVersionConstants.WEB_2_5_ID;
					}
				}
				break;
			case WEBSERVICES_TYPE:
				if (publicID != null && systemID != null) {
					if (publicID.equals(J2EEConstants.WEBSERVICE_PUBLICID) && (systemID.equals(J2EEConstants.WEBSERVICE_SYSTEMID))) {
						version = J2EEVersionConstants.WEBSERVICES_1_0_ID;
					}
				} else if (schemaName != null) {
					if (schemaName.equals(J2EEConstants.WEBSERVICE_SCHEMA_1_1)) {
						version = J2EEVersionConstants.WEBSERVICES_1_1_ID;
					} else if (schemaName.equals(J2EEConstants.WEBSERVICE_SCHEMA_1_2)) {
						version = J2EEVersionConstants.WEBSERVICES_1_2_ID;
					}
				}
				break;
			default:
				break;
			}
			if (version == UNSET) {
				version = UNKNOWN;
			}
		}
		return version;
	}

	/**
	 * Maps the version returned from {@link #getVersion()} to the Java EE spec
	 * version. For example, this is an EJB 3.0 deployment descriptor, this
	 * returns the constant for 5.0 (which maps to the Java EE spec version of
	 * 5.0). as defined by {@link J2EEVersionConstants}
	 * 
	 * @return
	 */
	public int getJavaEEVersion() {
		if (javaEEVersion == UNSET) {
			int type = getType();
			int version = getVersion();
			switch (type) {
			case APPLICATION_CLIENT_TYPE:
			case APPLICATION_TYPE:
				javaEEVersion = version;
				break;
			case EJB_TYPE:
				switch (version) {
				case J2EEVersionConstants.EJB_1_1_ID:
					javaEEVersion = J2EEVersionConstants.J2EE_1_2_ID;
					break;
				case J2EEVersionConstants.EJB_2_0_ID:
					javaEEVersion = J2EEVersionConstants.J2EE_1_3_ID;
					break;
				case J2EEVersionConstants.EJB_2_1_ID:
					javaEEVersion = J2EEVersionConstants.J2EE_1_4_ID;
					break;
				case J2EEVersionConstants.EJB_3_0_ID:
					javaEEVersion = J2EEConstants.JEE_5_0_ID;
				}
				break;
			case CONNECTOR_TYPE:
				switch (version) {
				case J2EEVersionConstants.JCA_1_0_ID:
					javaEEVersion = J2EEConstants.J2EE_1_3_ID;
					break;
				case J2EEVersionConstants.JCA_1_5_ID:
					javaEEVersion = J2EEConstants.J2EE_1_4_ID;
					break;
				}
				break;
			case WEB_TYPE:
				switch (version) {
				case J2EEVersionConstants.WEB_2_2_ID:
					javaEEVersion = J2EEVersionConstants.J2EE_1_2_ID;
					break;
				case J2EEVersionConstants.WEB_2_3_ID:
					javaEEVersion = J2EEVersionConstants.J2EE_1_3_ID;
					break;
				case J2EEVersionConstants.WEB_2_4_ID:
					javaEEVersion = J2EEVersionConstants.J2EE_1_4_ID;
					break;
				case J2EEVersionConstants.WEB_2_5_ID:
					javaEEVersion = J2EEVersionConstants.JEE_5_0_ID;
				}
				break;
		case WEBSERVICES_TYPE:
			switch (version) {
			case J2EEVersionConstants.WEBSERVICES_1_0_ID:
				javaEEVersion = J2EEVersionConstants.J2EE_1_3_ID;
				break;
			case J2EEVersionConstants.WEBSERVICES_1_1_ID:
				javaEEVersion = J2EEVersionConstants.J2EE_1_4_ID;
				break;
			case J2EEVersionConstants.WEBSERVICES_1_2_ID:
				javaEEVersion = J2EEVersionConstants.JEE_5_0_ID;
			}
			break;
		}
			if (javaEEVersion == UNSET) {
				javaEEVersion = UNKNOWN;
			}
		}
		return javaEEVersion;
	}

	public void setVersion(int version) {
		this.version = version;
	}

	public void setJavaEEVersion(int javaEEVersion) {
		this.javaEEVersion = javaEEVersion;
	}

	public void setType(int type) {
		this.type = type;
	}

}
