/**
 * Copyright (c) 2017 CEA.
 * 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:
 *     CEA - initial API and implementation and/or initial documentation
 */
/*
 * generated by Xtext 2.9.1
 */
package org.eclipse.sensinact.studio.language.validation

import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_AFTER
import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_BEFORE
import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_DURATION
import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_DURATION_MIN
import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_DURATION_SEC
import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_STATEMENT
import org.eclipse.sensinact.studio.language.sensinact.DSL_ListParam
import org.eclipse.sensinact.studio.language.sensinact.DSL_REF
import org.eclipse.sensinact.studio.language.sensinact.DSL_Resource
import org.eclipse.sensinact.studio.language.sensinact.DSL_ResourceAction
import org.eclipse.sensinact.studio.language.sensinact.DSL_SENSINACT
import org.eclipse.sensinact.studio.language.sensinact.SensinactPackage
import org.eclipse.sensinact.studio.model.manager.modelupdater.ModelEditor
import org.eclipse.sensinact.studio.resource.AccessMethodType
import java.math.BigDecimal
import org.eclipse.emf.ecore.EStructuralFeature
import org.eclipse.xtext.validation.Check
import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor
import org.eclipse.sensinact.studio.language.sensinact.impl.DSL_REFImpl

/**
 * This class contains custom validation rules. 
 *
 * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#validation
 */
class SensinactValidator extends AbstractSensinactValidator {
	
	def isConnected() {
		return ModelEditor.getInstance().getGatewaysId.length != 0;
	}

	@Check
	def checkGatewayIsConnected(DSL_SENSINACT eca) {
		if (!isConnected())
			warning("Please connect the studio to your gateway", SensinactPackage.Literals.DSL_SENSINACT__RESOURCES);
	}

	@Check
	def void refNameIsUnique(DSL_REF ref) {
		var nameOccurences = 0;
		var name = ref.getName();

		var superEntity = (ref.eContainer() as DSL_SENSINACT);
		if (superEntity != null) {
			for (other : superEntity.resources) {
				if (name.equals(other.getName())) {
					nameOccurences++;
				}
			}
			for (other : superEntity.cep) {
				if (name.equals(other.getName())) {
					nameOccurences++;
				}
			}

			if (nameOccurences > 1) {
				error("Reference names names have to be unique", SensinactPackage.Literals.DSL_REF__NAME, ref.getName());
			}
		}
	}

	@Check
	def checkResourceExists(DSL_Resource dslResource) {
		if (isConnected()) {
			var gatewayID = dslResource.gatewayID;
			var deviceID = dslResource.deviceID;
			var serviceID = dslResource.serviceID;
			var resourceID = dslResource.resourceID;

			if (! ModelEditor.getInstance().existsGateway(gatewayID)) {
				warning("The gateway " + gatewayID + " does not exist",
					SensinactPackage.Literals.DSL_RESOURCE__GATEWAY_ID, 'INVALID_NAME');
			} else if (! ModelEditor.getInstance().existsDevice(gatewayID, deviceID)) {
				warning("The device " + deviceID + " does not exist in gateway " + gatewayID,
					SensinactPackage.Literals.DSL_RESOURCE__DEVICE_ID, 'INVALID_NAME');
			} else if (! ModelEditor.getInstance().existsService(gatewayID, deviceID, serviceID)) {
				warning("The service " + serviceID + " does not exist in gateway " + gatewayID,
						SensinactPackage.Literals.DSL_RESOURCE__SERVICE_ID, 'INVALID_NAME');
			} else if (! ModelEditor.getInstance().existsResource(gatewayID, deviceID, serviceID, resourceID)) {
				warning("The resource " + resourceID + " does not exist in gateway " + gatewayID,
						SensinactPackage.Literals.DSL_RESOURCE__RESOURCE_ID, 'INVALID_NAME');
			}
		}
	}

	@Check
	def checkActionAccessMethod(DSL_ResourceAction resourceAction) {
		if (isConnected()) {
			var ref = resourceAction.ref;
			var AccessMethodType actionType = AccessMethodType.getByName(resourceAction.actiontype);
			var nbParams = getNbParams(resourceAction.listParam);
			checkParameters(ref, actionType, nbParams, SensinactPackage.Literals.DSL_RESOURCE_ACTION__ACTIONTYPE);
		}
	}

	def getNbParams(DSL_ListParam params) {
		if (params == null)
			return 0;
		if (params.param == null)
			return 0;
		return params.param.size;
	}

	def checkParameters(DSL_REF ref, AccessMethodType actionType, int nbParams, EStructuralFeature feature) {
		if (ref instanceof DSL_Resource) {

			var dslResource = ref as DSL_Resource;

			var gatewayID = dslResource.gatewayID;
			var deviceID = dslResource.deviceID;
			var serviceID = dslResource.serviceID;
			var resourceID = dslResource.resourceID;

			var descriptor = new ResourceDescriptor(gatewayID, deviceID, serviceID, resourceID);


			// finding method
			if (descriptor != null && actionType != null) {
				var method = ModelEditor.getInstance().getAccessMethodWithTypeNbParams(descriptor, actionType, nbParams);
												
				if (method == null) {
					var String msg = null;
					if (nbParams == 0) {
						msg = "This action type without parameters is not available for this resource";
					} else if (nbParams == 1) {
						msg = "This action type with one parameter is not available for this resource";
					} else if (nbParams == 0) {
						msg = "This action type with " + nbParams + " parameters is not available for this resource";
					}
					error(msg, feature);
				}
			}

		} else if (ref instanceof DSL_CEP_STATEMENT) {
			// no check
		} else if (ref.class.equals(typeof(DSL_REFImpl))) {
			// exact same class (no subclassing)
		} else {
			throw new RuntimeException("Should never happen");
		}
	}

	@Check
	def checkCepAfter(DSL_CEP_AFTER operation) {
		var start = timestamp(operation.start);
		var end = timestamp(operation.end);

		if (start.compareTo(end) >= 0) {
			var msg = "end must be after start";
			error(msg, SensinactPackage.Literals.DSL_CEP_AFTER__END);
		}
	}

	@Check
	def checkCepBefore(DSL_CEP_BEFORE operation) {
		var start = timestamp(operation.start);
		var end = timestamp(operation.end);

		if (start.compareTo(end) >= 0) {
			var msg = "end must be after start";
			error(msg, SensinactPackage.Literals.DSL_CEP_BEFORE__END);
		}
	}

	def timestamp(DSL_CEP_DURATION duration) {
		var retval = BigDecimal.ZERO;
		if (duration != null && duration.units != null) {
			for (unit : duration.units) {
				if (unit instanceof DSL_CEP_DURATION_MIN) {
					var min = unit as DSL_CEP_DURATION_MIN;
					retval = retval.add(min.min.multiply(new BigDecimal("60")));
				} else if (unit instanceof DSL_CEP_DURATION_SEC) {
					var sec = unit as DSL_CEP_DURATION_SEC;
					retval = retval.add(sec.sec);
				}
			}
		}
		return retval;
	}
	
}
