/**
 ********************************************************************************
 * Copyright (c) 2015-2018 Robert Bosch GmbH and others.
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Robert Bosch GmbH - initial API and implementation
 ********************************************************************************
 */

package org.eclipse.app4mc.amalthea.model.check;

import java.io.OutputStream;
import java.io.PrintStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;

import org.eclipse.app4mc.amalthea.model.Amalthea;
import org.eclipse.app4mc.amalthea.model.IReferable;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EContentsEList;
import org.eclipse.emf.ecore.util.EcoreUtil;

public class ModelStructureCheck {

	// Suppress default constructor
	private ModelStructureCheck() {
		throw new IllegalStateException("Utility class");
	}

	/**
	 * Model checker for debugging: Checks a single file model.
	 *
	 * Illegal references to non contained elements will be printed to stream.
	 *
	 * @param model   to-be-checked model (self contained)
	 * @param stream  output stream for messages (<code>null</code> -> disable messages)
	 * @param verbose <code>true</code> -> prints all performed checks
	 * @return <code>true</code> if everything was o.k.
	 */
	public static boolean checkModel(Amalthea model, PrintStream stream, boolean verbose) {
		return checkModels(Collections.singletonList(model), stream, verbose);
	}

	/**
	 * Model checker for debugging: Checks a model that consists of multiple files.
	 *
	 * Illegal references to non contained elements will be printed to stream.
	 *
	 * @param models  to-be-checked logical model (multiple split models)
	 * @param stream  output stream for messages (<code>null</code> -> disable messages)
	 * @param verbose <code>true</code> -> prints all performed checks
	 * @return <code>true</code> if everything was o.k.
	 */
	public static boolean checkModels(Collection<Amalthea> models, PrintStream stream, boolean verbose) {
		boolean result = true;
		DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");

		if (models == null || models.isEmpty())
			return false;

		try ( PrintStream nullStream = getNullPrintStream() ) {
			PrintStream out = (stream != null) ? stream : nullStream;

			out.println("++++ Model check startet at " + dateFormat.format(new Date()));

			// create map with Ids of contained referable objects

			HashMap<String, IReferable> idMap = new HashMap<>();

			for (Amalthea amalthea : models) {
				if (amalthea == null)
					return false;

				collectObjectIDs(amalthea, idMap, out);
			}

			// check references to top level types

			for (Amalthea amalthea : models) {
				boolean ok = checkObjectReferences(amalthea, idMap, out, verbose);
				result = result && ok;
			}

			// cleanup
			idMap.clear();

			out.println("++++ Model check finished at " + dateFormat.format(new Date()));
		}

		return result;
	}

	private static void collectObjectIDs(Amalthea model, HashMap<String, IReferable> idMap, PrintStream out) {
		final TreeIterator<EObject> iterator = EcoreUtil.getAllContents(model, false);
		while (iterator.hasNext()) {
			final EObject element = iterator.next();

			if (element instanceof IReferable) {
				final IReferable refObj = (IReferable) element;
				final String id = refObj.getUniqueName();
				if (idMap.containsKey(id)) {
					final IReferable oldObj = idMap.put(id, null);
					if (oldObj != null) {
						out.println("Name is not unique: " + id); // oldObj
					}
					out.println("Name is not unique: " + id); // refObj
				} else {
					idMap.put(id, refObj);
				}
			}
		}
	}

	private static boolean checkObjectReferences(Amalthea model, HashMap<String, IReferable> idMap, PrintStream out, boolean verbose) {
		boolean result = true;

		for (Iterator<EObject> objIter = model.eAllContents(); objIter.hasNext();) {
			EObject content = objIter.next();
			// iterate over all cross references
			for (EContentsEList.FeatureIterator<EObject> featureIterator = (EContentsEList.FeatureIterator<EObject>) content
					.eCrossReferences().iterator(); featureIterator.hasNext();) {
				EObject eObj = featureIterator.next();
				EReference eRef = (EReference) featureIterator.feature();

				if (eRef.isTransient())
					// ignore transient (back) references
					continue;

				if (!(eObj instanceof IReferable)) {
					// should never happen ! (indicates an error in the meta model)
					out.println(
							"ERROR -- unknown reference " + eRef.getName() + " to " + eObj.getClass().getSimpleName());
					continue;
				}

				IReferable refObj = (IReferable) eObj;
				if (idMap.containsKey(refObj.getUniqueName())) {
					if (verbose) {
						StringBuilder sb = new StringBuilder();
						sb.append("    reference: ");
						addReferenceDescription(eRef, content, refObj, sb);
						out.println(sb.toString());
					}
				} else {
					result = false;
					StringBuilder sb = new StringBuilder();
					sb.append("Illegal target: ");
					addReferenceDescription(eRef, content, refObj, sb);
					out.println(sb.toString());
				}
			}
		}
		return result;
	}

	private static PrintStream getNullPrintStream() {
		OutputStream nullOutputStream = new OutputStream() {
			@Override
			public void write(int b) { /* ignore write operations */ }
		};
		return new PrintStream(nullOutputStream);
	}

	private static String getName(EObject obj) {
		EStructuralFeature sf = obj.eClass().getEStructuralFeature("name");
		if (sf == null)
			return "";

		final String name = (String) obj.eGet(sf);
		if (name == null || name.length() == 0)
			return "???";

		return name;
	}

	private static void addShortString(EObject obj, StringBuilder sb) {
		sb.append(obj.getClass().getSimpleName());
		sb.append("@");
		sb.append(Integer.toHexString(obj.hashCode()));
	}

	private static void addReferenceDescription(EReference ref, EObject source, EObject target, StringBuilder sb) {
		addShortString(source, sb);
		sb.append("[ ");
		sb.append(getName(source));
		sb.append(" ] --- ");
		sb.append(ref.getName());
		sb.append(" --> ");
		addShortString(target, sb);
		sb.append("[ ");
		sb.append(getName(target));
		sb.append(" ]");
	}

}
