/*******************************************************************************
 * Copyright (c) 2015 The University of York.
 * 
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the Eclipse
 * Public License, v. 2.0 are satisfied: GNU General Public License, version 3.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-3.0
 *
 * Contributors:
 *     Antonio Garcia-Dominguez - initial API and implementation
 *     Orjuwan Al-Wadeai -  Integrate Modelio Metamodel 3.6
 ******************************************************************************/
package org.eclipse.hawk.modelio.exml.ecoregen;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.ETypedElement;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
import org.eclipse.hawk.core.model.IHawkAttribute;
import org.eclipse.hawk.core.model.IHawkClass;
import org.eclipse.hawk.core.model.IHawkClassifier;
import org.eclipse.hawk.core.model.IHawkReference;
import org.eclipse.hawk.modelio.exml.metamodel.ModelioAttribute;
import org.eclipse.hawk.modelio.exml.metamodel.ModelioClass;
import org.eclipse.hawk.modelio.exml.metamodel.ModelioMetaModelResource;
import org.eclipse.hawk.modelio.exml.metamodel.ModelioMetaModelResourceFactory;
import org.eclipse.hawk.modelio.exml.metamodel.ModelioPackage;
import org.eclipse.hawk.modelio.exml.metamodel.ModelioReference;
import org.eclipse.hawk.modelio.exml.metamodel.register.MetamodelRegister;

/**
 * Generates an <code>.ecore</code> file that mimics the Modelio metamodel, in
 * order to make it possible to load Modelio instances through
 * <code>.hawkmodel</code> and <code>.localhawkmodel</code> files.
 *
 * Also generates the appropriate plugin.xml entries to have these metamodels
 * included automatically in the default EMF EPackage registry.
 */
public class EcoreGenerator {

	protected static final class ClassifierNameComparator implements Comparator<IHawkClassifier> {
		@Override
		public int compare(IHawkClassifier o1, IHawkClassifier o2) {
			return o1.getName().compareTo(o2.getName());
		}
	}

	private final class Tuple<L, R> {
		private final L left;
		private final R right;

		private Tuple(L key, R value) {
			this.left = key;
			this.right = value;
		}

		public L getLeft() {
			return left;
		}

		public R getRight() {
			return right;
		}
	}

	private final EcoreFactory factory;
	private final List<EPackage> packages = new ArrayList<>();
	private final Map<String, Tuple<EClass, ModelioClass>> mClasses = new LinkedHashMap<>(); // classesById
	private int nPackage = 0;

	public static void main(String[] args) {
		try {
			// add modelio metamodel
			final File metamodelFile = new File("metamodel/metamodel_descriptor.xml");
			ModelioMetaModelResourceFactory factory;
			factory = new ModelioMetaModelResourceFactory();
			ModelioMetaModelResource metamodelResource = (ModelioMetaModelResource) factory.parse(metamodelFile);
			
			
			final EcoreGenerator generator = new EcoreGenerator();
			final File f = new File("model/modelioMetamodel_format_" + metamodelResource.getMetamodel().getFormat() + ".ecore");
			final Resource r = generator.generate(f);
			System.out.println("plugin.xml fragment:\n\n" + generator.generatePluginXml(r));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private String generatePluginXml(Resource r) {
		final StringBuffer sbuf = new StringBuffer();
		for (EPackage pkg : packages) {
			/*
			 * <resource location="model/modelio.ecore#/"
			 * uri="org.eclipse.hawk.modelio.exml.ecoregen.resource3">
			 */
			sbuf.append("    <resource uri=\"");
			sbuf.append(pkg.getNsURI());
			sbuf.append("\" location=\"");
			sbuf.append(r.getURI().toString() + "#" + r.getURIFragment(pkg));
			sbuf.append("\"/>\n");
		}
		return sbuf.toString();
	}

	public EcoreGenerator() {
		factory = EcorePackage.eINSTANCE.getEcoreFactory();
	}

	public Resource generate(File file) throws Exception {
		Resource r = new XMIResourceImpl(URI.createFileURI(file.getPath()));

		// Do a first pass to create the structure
		
		final Collection<ModelioPackage> mps = MetamodelRegister.INSTANCE.getRegisteredPackages();
		for (ModelioPackage mp : mps) {
			addPackageContents(r, mp);
		}

		// On the second pass, create features and references (sorted by names, to avoid unwanted diffs when regenerating)
		for (Tuple<EClass, ModelioClass> entry : mClasses.values()) {
			final EcorePackage ecorePkg = EcorePackage.eINSTANCE;
			final EClass ec = entry.getLeft();
			final ModelioClass mc = entry.getRight();

			final List<IHawkClass> superMClasses = new ArrayList<>(mc.getOwnSuperTypes());
			Collections.sort(superMClasses, new ClassifierNameComparator());
			for (IHawkClass superMClass : superMClasses) {
				EClass eSuper = mClasses.get(((ModelioClass)superMClass).getId()).getLeft();
				ec.getESuperTypes().add(eSuper);
			}

			final List<ModelioAttribute> mattrs = new ArrayList<>(mc.getOwnAttributesMap().values());
			Collections.sort(mattrs, new Comparator<IHawkAttribute>(){
				@Override
				public int compare(IHawkAttribute o1, IHawkAttribute o2) {
					return o1.getName().compareTo(o2.getName());
				}
			});
			for (IHawkAttribute mattr : mattrs) {
				EDataType edt = ecorePkg.getEString();
				final String javaEquivalent = ((ModelioAttribute)mattr).getRawAttribute().getMDataType().getJavaEquivalent().replaceAll("java[.]lang[.]", "");
				switch (javaEquivalent) {
				case "Short":
					edt = ecorePkg.getEShort();
					break;
				case "Long":
					edt = ecorePkg.getELong();
					break;
				case "Integer":
					edt = ecorePkg.getEInt();
					break;
				case "Float":
					edt = ecorePkg.getEFloat();
					break;
				case "Double":
					edt = ecorePkg.getEDouble();
					break;
				case "Character":
					edt = ecorePkg.getEChar();
					break;
				case "Byte":
					edt = ecorePkg.getEByte();
					break;
				case "Boolean":
					edt = ecorePkg.getEBoolean();
					break;
				case "String":
				case "enum":
					break;
				default:
					System.err.println("Unknown type " + javaEquivalent + ", using String");
					break;
				}

				final EAttribute eattr = factory.createEAttribute();
				eattr.setName(mattr.getName());
				eattr.setEType(edt);
				eattr.setOrdered(mattr.isOrdered());
				eattr.setUnique(mattr.isUnique());
				eattr.setUpperBound(mattr.isMany() ? EAttribute.UNBOUNDED_MULTIPLICITY : 1);
				ec.getEStructuralFeatures().add(eattr);
			}

			final List<ModelioReference> mdeps = new ArrayList<>(mc.getOwnReferencesMap().values());
			Collections.sort(mdeps, new Comparator<IHawkReference>(){
				@Override
				public int compare(IHawkReference o1, IHawkReference o2) {
					return o1.getName().compareTo(o2.getName());
				}
			});
			for (IHawkReference mdep : mdeps) {
				final EClass targetEClass = mClasses.get(((ModelioClass)mdep.getType()).getId()).getLeft();

				final EReference eref = factory.createEReference();
				eref.setName(mdep.getName());
				eref.setOrdered(mdep.isOrdered());
				eref.setUnique(mdep.isUnique());
				eref.setUpperBound(mdep.isMany() ? EReference.UNBOUNDED_MULTIPLICITY : 1);
				eref.setEType(targetEClass);
				eref.setContainment(mdep.isContainment());
				ec.getEStructuralFeatures().add(eref);
			}

			if (mc.getAllSuperTypes().isEmpty()) {
				final EReference eRefParent = (EReference) ec.getEStructuralFeature(ModelioClass.REF_PARENT);

				final EReference eRefChildren = factory.createEReference();
				eRefChildren.setName(ModelioClass.REF_CHILDREN);
				eRefChildren.setOrdered(true);
				eRefChildren.setUnique(true);
				eRefChildren.setUpperBound(ETypedElement.UNBOUNDED_MULTIPLICITY);

				// The hawkParent reference's eType should be the root class that defines the reference itself
				eRefChildren.setEType(eRefParent.getEType());
				eRefChildren.setContainment(true);

				eRefChildren.setEOpposite(eRefParent);
				eRefParent.setEOpposite(eRefChildren);

				ec.getEStructuralFeatures().add(eRefChildren);
			}
		}

		r.save(null);
		return r;
	}

	private void addPackageContents(Resource r, final ModelioPackage pkg) throws Exception {
		EPackage ep = factory.createEPackage();
		ep.setName(pkg.getName());
		ep.setNsPrefix("m" + nPackage++);
		ep.setNsURI(pkg.getNsURI());
		r.getContents().add(ep);
		this.packages.add(ep);

		// Sort by name (getClasses returns a set, not a list)
		List<IHawkClassifier> classes = new ArrayList<>(pkg.getClasses());
		Collections.sort(classes, new ClassifierNameComparator());

		for (final IHawkClassifier mc : classes) {
			final EClass ec = factory.createEClass();
			ec.setName(mc.getName());
			ep.getEClassifiers().add(ec);

			final Tuple<EClass, ModelioClass> previousEntry = mClasses.put(((ModelioClass)mc).getId(), new Tuple<>(ec, (ModelioClass) mc));
			if (previousEntry != null) {
				throw new Exception("More than one class named " + mc.getName() + ": aborting");
			}
		}
		for (ModelioPackage subpkg : pkg.getPackages()) {
			addPackageContents(r, subpkg);
		}
	}
}
