/*******************************************************************************
 * Copyright (c) 2003, 2004 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.wst.common.internal.emfworkbench.operation;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
import org.eclipse.emf.codegen.ecore.genmodel.GenModelFactory;
import org.eclipse.emf.codegen.ecore.genmodel.GenPackage;
import org.eclipse.emf.codegen.ecore.java2ecore.JavaEcoreBuilder;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.wst.common.framework.operation.WTPOperation;
import org.eclipse.xsd.XSDPackage;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.ecore.XSDEcoreBuilder;

import com.ibm.wtp.common.logger.proxy.Logger;
import com.ibm.wtp.emf.workbench.WorkbenchResourceHelperBase;

/**
 * @author delfinoj
 * 
 * Generates SDO DataObject classes.
 *  
 */
public class DataObjectGenerator extends WTPOperation {
	protected IProject project;
	protected List xmiPackages;
	protected List javaModels;
	protected XSDEcoreBuilder xsdECoreBuilder;
	protected List ePackages;

	/**
	 * @param operationDataModel
	 */
	public DataObjectGenerator(DataObjectGeneratorModel operationDataModel) {
		super(operationDataModel);
	}

	/**
	 * Set the nsURI of the <code>ePackage</code> to be in the form
	 * "java://{fullyQualifiedPackageInterfaceName}. When this format is used, EMF will attempt to
	 * register the static package by loading the interface and calling the eINSTANCE field.
	 * 
	 * @param ePackage
	 * @param fullyQualifiedPackageInterfaceName
	 */
	public static void setStaticPackageNsURI(EPackage ePackage, String fullyQualifiedPackageInterfaceName) {
		if (ePackage != null && fullyQualifiedPackageInterfaceName != null)
			ePackage.setNsURI("java://" + fullyQualifiedPackageInterfaceName);//$NON-NLS-1$
	}

	protected IProject getProject() {
		if (project == null)
			project = (IProject) operationDataModel.getProperty(DataObjectGeneratorModel.PROJECT);
		return project;
	}

	protected XSDEcoreBuilder getXSDEcoreBuilder() {
		if (xsdECoreBuilder == null)
			xsdECoreBuilder = new XSDEcoreBuilder();
		return xsdECoreBuilder;
	}

	/**
	 * @see com.ibm.etools.ctc.ant.task.util.BaseProjectBuilder#generate(org.eclipse.core.runtime.IProgressMonitor)
	 */
	protected boolean prepareGenerate() throws CoreException {
		// Collect all generated EPackages
		ePackages = new ArrayList();
		// Packages generated from XSDs
		if (xsdECoreBuilder != null)
			ePackages.addAll(xsdECoreBuilder.getTargetNamespaceToEPackageMap().values());
		// Packages loaded from XMI files
		if (xmiPackages != null)
			ePackages.addAll(xmiPackages);
		if (javaModels != null)
			prepareEPackagesFromJavaModels();
		if (ePackages.isEmpty())
			return false;
		return true;
	}

	protected void prepareEPackagesFromJavaModels() {
		// Generate packages from annotated java model files
		JavaEcoreBuilder javaEcoreBuilder = new JavaEcoreBuilder(getProject().getFile(new Path("sdo.genmodel"))) { //$NON-NLS-1$
			public void getAllGenModelFiles(Collection result, IFile file) throws CoreException {
				// Ignore .genmodel files on the buildpath
				return;
			}
		};
		javaEcoreBuilder.run(new NullProgressMonitor(), false);
		IStatus localStatus = javaEcoreBuilder.getStatus();
		if (localStatus.getSeverity() != IStatus.ERROR) {
			List genPackages = javaEcoreBuilder.getGenModel().getGenPackages();
			processGenPackagesFromJavaModels(genPackages);
		} else
			logProblems(localStatus);
	}

	/**
	 * @param statusArg
	 */
	private void logProblems(IStatus statusArg) {
		Logger logger = Logger.getLogger();
		logger.logError("Problems detected generating SDO objects."); //$NON-NLS-1$
		log(statusArg, logger);
	}

	private void log(IStatus statusArg, Logger logger) {
		doLog(statusArg, logger);
		if (statusArg.isMultiStatus()) {
			MultiStatus mStatus = (MultiStatus) statusArg;
			IStatus[] children = mStatus.getChildren();
			for (int i = 0; i < children.length; i++) {
				log(children[i], logger);
			}
		}
	}

	private void doLog(IStatus statusArg, Logger logger) {
		switch (statusArg.getSeverity()) {
			case IStatus.ERROR :
				logger.logError(statusArg.getMessage());
				break;
			case IStatus.WARNING :
				logger.logWarning(statusArg.getMessage());
				break;
			case IStatus.INFO :
				logger.log(statusArg.getMessage());
				break;
		}
	}

	/**
	 * @param genPackages
	 */
	protected void processGenPackagesFromJavaModels(List genPackages) {
		if (genPackages.isEmpty())
			return;
		for (Iterator i = genPackages.iterator(); i.hasNext();) {
			GenPackage genPackage = (GenPackage) i.next();
			EPackage ePackage = genPackage.getEcorePackage();
			updateEPackageFromJavaModel(ePackage, genPackage);
			ePackages.add(ePackage);
		}

	}

	protected void updateEPackageFromJavaModel(EPackage ePackage, GenPackage genPackage) {
		// Fix the ePackage name
		ePackage.setName(ePackage.getNsPrefix());
		setStaticPackageNsURI(ePackage, genPackage);
	}

	/**
	 * Since we are generating static Packages we need to set the nsURI of each EPackage to be in
	 * the form "java://{fully qualified package interface name}. When this format is used, EMF will
	 * attempt to register the static package by loading the interface and calling the eINSTANCE
	 * field.
	 * 
	 * @param ePackage
	 * @param genPackage
	 */
	protected void setStaticPackageNsURI(EPackage ePackage, GenPackage genPackage) {
		String interfaceName = genPackage.getPackageInterfaceName();
		if (interfaceName != null) {
			StringBuffer b = new StringBuffer();
			b.append(genPackage.getPackageName()).append('.').append(interfaceName);
			setStaticPackageNsURI(ePackage, b.toString());
		}
	}

	/**
	 * @see com.ibm.etools.ctc.ant.task.util.BaseProjectBuilder#generate(org.eclipse.core.runtime.IProgressMonitor)
	 */
	protected void generate(IProgressMonitor progressMonitor) throws CoreException {
		try {
			progressMonitor.beginTask(getProject().getFullPath().toString(), 100);
			// Create a GenModel
			GenModel genModel = GenModelFactory.eINSTANCE.createGenModel();
			initializeGenModel(genModel);
			setPackagesOnGenModel(genModel);
			// Validate the GenModel
			IStatus localStatus = genModel.validate();
			if (!localStatus.isOK())
				throw new CoreException(localStatus);
			doGenerate(progressMonitor, genModel);
			progressMonitor.worked(100);
		} finally {
			progressMonitor.done();
		}
	}

	/*
	 * Generate static code.
	 */
	protected void doGenerate(IProgressMonitor progressMonitor, GenModel genModel) {
		try {
			genModel.generate(new SubProgressMonitor(progressMonitor, 50));
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}

	/*
	 * Initialize the GenModel from the EPackages
	 */
	protected void setPackagesOnGenModel(GenModel genModel) {
		genModel.initialize(ePackages);
		for (Iterator i = genModel.getGenPackages().iterator(); i.hasNext();) {
			GenPackage genPackage = (GenPackage) i.next();
			genPackage.setLoadInitialization(false);
			String prefix = genPackage.getInterfacePackageName();
			prefix = prefix.substring(prefix.lastIndexOf('.') + 1);
			if (prefix.length() > 1)
				prefix = prefix.substring(0, 1).toUpperCase() + prefix.substring(1);
			else
				prefix = prefix.toUpperCase();
			genPackage.setPrefix(prefix);
		}
	}

	/**
	 * @param genModel
	 */
	protected void initializeGenModel(GenModel genModel) {
		setSDODefaults(genModel);

		genModel.setDynamicTemplates(operationDataModel.getBooleanProperty(DataObjectGeneratorModel.DYNAMIC_TEMPLATES));
		genModel.setForceOverwrite(operationDataModel.getBooleanProperty(DataObjectGeneratorModel.FORCE_OVERWRITE));
		genModel.setCanGenerate(operationDataModel.getBooleanProperty(DataObjectGeneratorModel.CAN_GENERATE));
		genModel.setUpdateClasspath(operationDataModel.getBooleanProperty(DataObjectGeneratorModel.UPDATE_CLASSPATH));
		genModel.setGenerateSchema(operationDataModel.getBooleanProperty(DataObjectGeneratorModel.GENERATE_SCHEMA));
		genModel.setNonNLSMarkers(operationDataModel.getBooleanProperty(DataObjectGeneratorModel.NON_NLS_MARKERS));

		IFolder modelDir = (IFolder) operationDataModel.getProperty(DataObjectGeneratorModel.MODEL_DIR);
		genModel.setModelDirectory(modelDir.getFullPath().toOSString());
	}

	/*
	 * Options from SetDefaultSDOOptions, recommended by Ed
	 */
	protected void setSDODefaults(GenModel genModel) {
		genModel.setRootExtendsInterface(""); //$NON-NLS-1$
		//TODO why would you expose this internal interface in the generated code, instead of
		// commonj.sdo.DataObject
		genModel.setRootImplementsInterface("org.eclipse.emf.ecore.sdo.InternalEDataObject"); //$NON-NLS-1$
		genModel.setRootExtendsClass("org.eclipse.emf.ecore.sdo.impl.EDataObjectImpl"); //$NON-NLS-1$
		genModel.setFeatureMapWrapperInterface("commonj.sdo.Sequence"); //$NON-NLS-1$
		genModel.setFeatureMapWrapperInternalInterface("org.eclipse.emf.ecore.sdo.util.ESequence"); //$NON-NLS-1$
		genModel.setFeatureMapWrapperClass("org.eclipse.emf.ecore.sdo.util.BasicESequence"); //$NON-NLS-1$
		genModel.setSuppressEMFTypes(true);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.common.framework.operation.WTPOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
	 */
	protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException {
		loadModelFiles(monitor);
		if (prepareGenerate())
			generate(monitor);
	}

	/**
	 * @param monitor
	 */
	protected void loadModelFiles(IProgressMonitor monitor) {
		loadXSDFiles(monitor);
		loadEcoreFiles(monitor);
		//loadWSDLFiles(monitor);
		loadJavaFiles(monitor);
	}

	/**
	 * Load an XSD and generate the eCore packages for each tracked XSD file.
	 * 
	 * @param monitor
	 */
	protected void loadXSDFiles(IProgressMonitor monitor) {
		if (operationDataModel.isSet(DataObjectGeneratorModel.XSD_FILES)) {
			List files = (List) operationDataModel.getProperty(DataObjectGeneratorModel.XSD_FILES);
			IFile file;
			for (int i = 0; i < files.size(); i++) {
				file = (IFile) files.get(i);
				Resource resource = WorkbenchResourceHelperBase.load(file);
				Collection xsdSchemas = EcoreUtil.getObjectsByType(resource.getContents(), XSDPackage.eINSTANCE.getXSDSchema());
				for (Iterator j = xsdSchemas.iterator(); j.hasNext();) {
					getXSDEcoreBuilder().generate((XSDSchema) j.next());
				}
			}
		}
	}

	/**
	 * Load an Ecore model file and generate the eCore packages for each tracked Ecore file.
	 * 
	 * @param monitor
	 */
	protected void loadEcoreFiles(IProgressMonitor monitor) {
		if (operationDataModel.isSet(DataObjectGeneratorModel.ECORE_FILES)) {
			List files = (List) operationDataModel.getProperty(DataObjectGeneratorModel.ECORE_FILES);
			IFile file;
			for (int i = 0; i < files.size(); i++) {
				file = (IFile) files.get(i);

				Resource resource = WorkbenchResourceHelperBase.getResource(file, true);
				addXmiPackages(resource.getContents());
			}
		}
	}


	protected void addXmiPackages(List packages) {
		if (xmiPackages == null)
			xmiPackages = new ArrayList();
		xmiPackages.addAll(packages);
	}

	/**
	 * Load the XSD files and generate the eCore packages for each tracked WSDL file.
	 * 
	 * @param monitor
	 */
	protected void loadWSDLFiles(IProgressMonitor monitor) {
		//		if (operationDataModel.isSet(DataObjectGeneratorModel.WSDL_FILES)) {
		//			List files = (List) operationDataModel.getProperty(DataObjectGeneratorModel.WSDL_FILES);
		//			IFile file;
		//			for (int i = 0; i < files.size(); i++) {
		//				file = (IFile) files.get(i);
		//				//TODO We can't handle WSDL in WSAD 5.1 as the WSDL model is not an EMF 2.0 model
		//				// Re-activate this function when we move to 6.0
		//				// // Load a WSDL file and collect all the references XSD schemas
		//				// Set xsdSchemas=new HashSet();
		//				// URI uri = URI.createFileURI(file.getLocation().toString());
		//				// Resource resource = WorkbenchResourceHelper.getResource(uri);
		//				// for (Iterator i=resource.getAllContents(); i.hasNext(); ) {
		//				// Object object=i.next();
		//				// if (object instanceof XSDSchemaExtensibilityElement) {
		//				// XSDSchemaExtensibilityElement
		//				// extensibilityElement=(XSDSchemaExtensibilityElement)object;
		//				// XSDSchema xsdSchema=extensibilityElement.getEXSDSchema();
		//				// if (xsdSchema!=null)
		//				// xsdSchemas.add(xsdSchema);
		//				// } else if (object instanceof Part) {
		//				// Part part=(Part)object;
		//				// XSDNamedComponent xsdComponent=part.getEXSDType();
		//				// if (xsdComponent==null)
		//				// xsdComponent=part.getEXSDElement();
		//				// if (xsdComponent!=null) {
		//				// XSDSchema xsdSchema=xsdComponent.getSchema();
		//				// if (xsdSchema!=null &&
		//				// !XSDUtil.isSchemaForSchemaNamespace(xsdSchema.getTargetNamespace())) {
		//				// xsdSchemas.add(xsdSchema);
		//				// }
		//				// }
		//				// }
		//				// }
		//				//
		//				// // Generate Ecore packages from XSDs
		//				// for (Iterator i=xsdSchemas.iterator(); i.hasNext(); )
		//				// xsdECoreBuilder.generate((XSDSchema)i.next());
		//				// }
		//			}
		//		}
	}

	/**
	 * Load an Ecore model file and generate the eCore packages for each tracked Ecore file.
	 * 
	 * @param monitor
	 */
	protected void loadJavaFiles(IProgressMonitor monitor) {
		javaModels = (List) operationDataModel.getProperty(DataObjectGeneratorModel.JAVA_FILES);
	}
}