/* Copyright (c) 2019 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;

import java.util.Set;

import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.DiagnosticChain;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.jdt.annotation.NonNull;

/**
 * This class provides static methods that implement validations (invariants) of the Amalthea EMF model.
 * <p>
 * The methods are called from several generated model objects.
 */

public class AmaltheaValidations {

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

	private static final String DIAGNOSTIC_SOURCE = "org.eclipse.app4mc.amalthea.model";
	private static final int NO_INDEX = -1;

	private static final AmaltheaPackage PACKAGE = AmaltheaPackage.eINSTANCE;

	public static boolean validateInvariants(MinAvgMaxStatistic obj, DiagnosticChain diagnostics) {
		boolean isValid = obj.getMin() <= obj.getAvg() && obj.getAvg() <= obj.getMax();
		if (!isValid) {
			addError(obj, PACKAGE.getMinAvgMaxStatistic_Avg(), "MinAvgMaxStatistic: constraint min <= avg <= max violated", diagnostics);
		}
		return isValid;
	}

	// ******** Interval bounds + Average (if available) ********

	public static boolean validateInvariants(TimeInterval obj, DiagnosticChain diagnostics) {
		return checkMinAvgMax(obj, diagnostics, obj.getLowerBound(), getAverage(obj), obj.getUpperBound());
	}

	public static boolean validateInvariants(DiscreteValueInterval obj, DiagnosticChain diagnostics) {
		return checkMinAvgMax(obj, diagnostics, toDouble(obj.getLowerBound()), getAverage(obj), toDouble(obj.getUpperBound()));
	}

	public static boolean validateInvariants(ContinuousValueInterval obj, DiagnosticChain diagnostics) {
		return checkMinAvgMax(obj, diagnostics, obj.getLowerBound(), getAverage(obj), obj.getUpperBound());
	}

	// ******** Truncated distribution bounds (mean is not limited) ********

	public static boolean validateInvariants(TruncatedTimeDistribution obj, DiagnosticChain diagnostics) {
		return checkMinAvgMax(obj, diagnostics, obj.getLowerBound(), null, obj.getUpperBound());
	}

	public static boolean validateInvariants(TruncatedDiscreteValueDistribution obj, DiagnosticChain diagnostics) {
		return checkMinAvgMax(obj, diagnostics, toDouble(obj.getLowerBound()), null, toDouble(obj.getUpperBound()));
	}

	public static boolean validateInvariants(TruncatedContinuousValueDistribution obj, DiagnosticChain diagnostics) {
		return checkMinAvgMax(obj, diagnostics, obj.getLowerBound(), null, obj.getUpperBound());
	}

	// private methods to get the given average / mean value

	private static Time getAverage(TimeInterval obj) {
		Time avg = null;
		if (obj instanceof TimeStatistics) {
			avg = ((TimeStatistics) obj).getAverage();
		}
		if (obj instanceof TimeWeibullEstimatorsDistribution) {
			avg = ((TimeWeibullEstimatorsDistribution) obj).getAverage();
		}
		return avg;
	}

	private static Double getAverage(DiscreteValueInterval obj) {
		Double avg = null;
		if (obj instanceof DiscreteValueStatistics) {
			avg = ((DiscreteValueStatistics) obj).getAverage();
		}
		if (obj instanceof DiscreteValueWeibullEstimatorsDistribution) {
			avg = ((DiscreteValueWeibullEstimatorsDistribution) obj).getAverage();
		}
		return avg;
	}

	private static Double getAverage(ContinuousValueInterval obj) {
		Double avg = null;
		if (obj instanceof ContinuousValueStatistics) {
			avg = ((ContinuousValueStatistics) obj).getAverage();
		}
		if (obj instanceof ContinuousValueWeibullEstimatorsDistribution) {
			avg = ((ContinuousValueWeibullEstimatorsDistribution) obj).getAverage();
		}
		return avg;
	}

	private static Double toDouble(Long value) {
		if (value == null) return null;

		return value.doubleValue();
	}

	private static <T extends Comparable<T>> boolean checkMinAvgMax(EObject obj, DiagnosticChain diagnostics, T min, T avg, T max) {
		boolean isValid = true;
		if (min != null && max != null && min.compareTo(max) > 0) {
			addError(obj, null, obj.eClass().getName() + ": lower bound > upper bound", diagnostics);
			isValid = false;
		}
		if (min != null && avg != null && min.compareTo(avg) > 0) {
			addError(obj, null, obj.eClass().getName() + ": lower bound > average", diagnostics);
			isValid = false;
		}
		if (avg != null && max != null && avg.compareTo(max) > 0) {
			addError(obj, null, obj.eClass().getName() + ": average > upper bound", diagnostics);
			isValid = false;
		}
		return isValid;
	}

	// ******** IReferable name (empty or duplicate) ********

	public static boolean validateInvariants(IReferable obj, DiagnosticChain diagnostics) {
		String shortName = obj.getName();
		if (shortName == null || shortName.isEmpty()) {
			addError(obj, PACKAGE.getINamed_Name(), obj.eClass().getName() + ": missing name", diagnostics);
			return false;
		}

		Set<? extends @NonNull IReferable> duplicates = AmaltheaIndex.getElements(obj, shortName, obj.getClass());
		if (duplicates.size() > 1) {
			String longName = obj.getQualifiedName();
			if (duplicates.stream().anyMatch(e -> e != obj && longName.equals(e.getQualifiedName()))) {
				addError(obj, PACKAGE.getINamed_Name(), obj.eClass().getName() + ": duplicate name", diagnostics);
				return false;
			}
		}
		
		return true;
	}

	// ******** Modes and Local Modes ********

	public static boolean validateInvariants(LocalModeLabel obj, DiagnosticChain diagnostics) {
		return checkModeAndValue(obj, PACKAGE.getLocalModeLabel_DefaultValue(), obj.getMode(), obj.getDefaultValue(), diagnostics);
	}

	public static boolean validateInvariants(LocalModeValue obj, DiagnosticChain diagnostics) {
		if  (obj.getLabel() != null && obj.getValueSource() != null) {
			LocalModeLabel label = obj.getLabel();
			ILocalModeValueSource source = obj.getValueSource();

			if ((label.isEnum() && source.isNumeric()) || (label.isNumeric() && source.isEnum())) {
				addError(obj, PACKAGE.getLocalModeValue_ValueSource(), obj.eClass().getName() + ": incompatible types", diagnostics);
				return false;
			}

			return checkModeCompatibility(obj, PACKAGE.getLocalModeValue_ValueSource(), label.getMode(), source.getMode(), diagnostics);
		}

		return true;
	}

	public static boolean validateInvariants(ModeLabel obj, DiagnosticChain diagnostics) {
		return checkModeAndValue(obj, PACKAGE.getModeLabel_InitialValue(), obj.getMode(), obj.getInitialValue(), diagnostics);
	}

	public static boolean validateInvariants(ModeValue obj, DiagnosticChain diagnostics) {
		ModeLabel modeLabel = obj.getLabel();
		if (modeLabel == null) {
			// This case is already handled by standard EMF validations (definition ModeLabel[1])
			// Manual diagnostics entry would be:
			// addError(obj, PACKAGE.getModeValue_Label(), obj.eClass().getName() + ": missing mode label", diagnostics)
			return false;
		}

		return checkModeAndValue(obj, PACKAGE.getModeValue_Value(), modeLabel.getMode(), obj.getValue(), diagnostics);
	}

	public static boolean validateInvariants(ModeLabelAccess obj, DiagnosticChain diagnostics) {
		ModeLabel modeLabel = obj.getData();
		if (modeLabel == null) {
			// This case is already handled by standard EMF validations (definition ModeLabel[1])
			// Manual diagnostics entry would be:
			// addError(obj, PACKAGE.getModeLabelAccess_Data(), obj.eClass().getName() + ": missing mode label", diagnostics)
			return false;
		}

		if (obj.getAccess() == ModeLabelAccessEnum.SET) {
			return checkModeAndValue(obj, PACKAGE.getModeLabelAccess_Value(), modeLabel.getMode(), obj.getValue(), diagnostics);
		}

		return true;
	}

	public static boolean validateInvariants(ModeLabelAssignment obj, DiagnosticChain diagnostics) {
		if  (obj.getGlobalLabel() != null && obj.getLocalLabel() != null) {
			ModeLabel label1 = obj.getGlobalLabel();
			LocalModeLabel label2 = obj.getLocalLabel();

			return checkModeCompatibility(obj, PACKAGE.getModeLabelAssignment_LocalLabel(), label1.getMode(), label2.getMode(), diagnostics);
		}

		return true;
	}

	public static boolean validateInvariants(ModeLabelCondition obj, DiagnosticChain diagnostics) {
		if  (obj.getLabel1() != null && obj.getLabel2() != null) {
			ModeLabel label1 = obj.getLabel1();
			ModeLabel label2 = obj.getLabel2();

			return checkModeCompatibility(obj, PACKAGE.getModeLabelAssignment_LocalLabel(), label1.getMode(), label2.getMode(), diagnostics);
		}

		return true;
	}

	private static boolean checkModeAndValue(EObject obj, EStructuralFeature feature, Mode mode, String value, DiagnosticChain diagnostics) {
		if (mode == null) {
			addWarning(obj, feature, obj.eClass().getName() + ": unknown value type (mode)", diagnostics);
			return false;
		}

		if (value == null) {
			if (feature.getLowerBound() != 0) {
				addError(obj, feature, obj.eClass().getName() + ": missing value", diagnostics);
				return false;
			} else {
				// value does not have to be set
				return true;
			}
		}

		String trimmedValue = value.trim();
		if (mode instanceof EnumMode) {
			final EnumMode enumMode = (EnumMode) mode;
			if (enumMode.getLiteral(trimmedValue) == null) {
				addError(obj, feature, "The " + feature.getName() + " '" + trimmedValue + "' is not a valid literal of Enum Mode \"" + mode.getName() + "\"", diagnostics);
				return false;
			}
		}

		if (mode instanceof NumericMode) {
			boolean isInteger = trimmedValue.matches("-?\\d+");
			if (!isInteger) {
				addError(obj, feature, "The " + feature.getName() + " '" + trimmedValue + "' is not an integer", diagnostics);
				return false;
			}
		}

		return true;
	}

	private static boolean checkModeCompatibility(EObject obj, EStructuralFeature feature, Mode mode1, Mode mode2, DiagnosticChain diagnostics) {
		if (mode1 != null && mode2 != null && !mode1.equals(mode2)) {
			addError(obj, feature, obj.eClass().getName() + ": incompatible modes", diagnostics);
			return false;
		}

		return true;
	}

	// private helper methods

	private static void addWarning(EObject object, EStructuralFeature feature, String message, DiagnosticChain diagnostics) {
    	if (diagnostics != null) {
        	diagnostics.add(createIssue(Diagnostic.WARNING, object, feature, message));
    	}
	}

	private static void addError(EObject object, EStructuralFeature feature, String message, DiagnosticChain diagnostics) {
    	if (diagnostics != null) {
        	diagnostics.add(createIssue(Diagnostic.ERROR, object, feature, message));
    	}
	}

	private static BasicDiagnostic createIssue(int severity, EObject object, EStructuralFeature feature, String message) {
		return new BasicDiagnostic(
				severity,
				DIAGNOSTIC_SOURCE,
				NO_INDEX,
		 		message,
		 		new Object [] { object, feature });
	}

}
