/*******************************************************************************
 * 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.jem.util.emf.workbench.WorkbenchResourceHelperBase;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.wst.common.frameworks.internal.operations.WTPOperation;
import org.eclipse.xsd.XSDPackage;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.ecore.XSDEcoreBuilder;

/**
 * @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() {
		// 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.frameworks.internal.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);
	}
}