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