/********************************************************************************
 * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 ********************************************************************************/

package org.eclipse.mdm.api.odsadapter.lookup.config;

import java.util.Locale;

import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.adapter.Relation;
import org.eclipse.mdm.api.base.model.Channel;
import org.eclipse.mdm.api.base.model.ChannelGroup;
import org.eclipse.mdm.api.base.model.ContextComponent;
import org.eclipse.mdm.api.base.model.ContextRoot;
import org.eclipse.mdm.api.base.model.ContextSensor;
import org.eclipse.mdm.api.base.model.ContextType;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.model.Environment;
import org.eclipse.mdm.api.base.model.Measurement;
import org.eclipse.mdm.api.base.model.Parameter;
import org.eclipse.mdm.api.base.model.ParameterSet;
import org.eclipse.mdm.api.base.model.PhysicalDimension;
import org.eclipse.mdm.api.base.model.Quantity;
import org.eclipse.mdm.api.base.model.Sortable;
import org.eclipse.mdm.api.base.model.Test;
import org.eclipse.mdm.api.base.model.TestStep;
import org.eclipse.mdm.api.base.model.Unit;
import org.eclipse.mdm.api.base.model.User;
import org.eclipse.mdm.api.dflt.model.CatalogAttribute;
import org.eclipse.mdm.api.dflt.model.CatalogComponent;
import org.eclipse.mdm.api.dflt.model.CatalogSensor;
import org.eclipse.mdm.api.dflt.model.Classification;
import org.eclipse.mdm.api.dflt.model.Domain;
import org.eclipse.mdm.api.dflt.model.Pool;
import org.eclipse.mdm.api.dflt.model.Project;
import org.eclipse.mdm.api.dflt.model.ProjectDomain;
import org.eclipse.mdm.api.dflt.model.Role;
import org.eclipse.mdm.api.dflt.model.Status;
import org.eclipse.mdm.api.dflt.model.TemplateAttribute;
import org.eclipse.mdm.api.dflt.model.TemplateComponent;
import org.eclipse.mdm.api.dflt.model.TemplateRoot;
import org.eclipse.mdm.api.dflt.model.TemplateSensor;
import org.eclipse.mdm.api.dflt.model.TemplateTest;
import org.eclipse.mdm.api.dflt.model.TemplateTestStep;
import org.eclipse.mdm.api.dflt.model.TemplateTestStepUsage;
import org.eclipse.mdm.api.dflt.model.ValueList;
import org.eclipse.mdm.api.dflt.model.ValueListValue;
import org.eclipse.mdm.api.dflt.model.Versionable;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig.Key;
import org.eclipse.mdm.api.odsadapter.query.ODSEntityType;
import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
import org.eclipse.mdm.api.odsadapter.utils.ODSUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DefaultEntityConfigRepositoryLoader implements EntityConfigRepositoryLoader {

	private static final Logger LOGGER = LoggerFactory.getLogger(DefaultEntityConfigRepositoryLoader.class);

	EntityConfigRepository entityConfigRepository;

	public DefaultEntityConfigRepositoryLoader() {
	}

	/**
	 * Loads the {@link EntityConfig}s.
	 * 
	 * @return
	 */
	@Override
	public EntityConfigRepository loadEntityConfigurations(ODSModelManager modelManager) {
		LOGGER.debug("Loading entity configurations...");
		long start = System.currentTimeMillis();

		entityConfigRepository = new EntityConfigRepository();

		entityConfigRepository.register(create(modelManager, new Key<>(Role.class), "Role", false));

		// Environment | Project | Pool | PhysicalDimension | User | Measurement
		// | ChannelGroup
		entityConfigRepository.register(create(modelManager, new Key<>(Environment.class), "Environment", false));
		entityConfigRepository.register(create(modelManager, new Key<>(Project.class), "Project", false));
		entityConfigRepository.register(create(modelManager, new Key<>(Pool.class), "StructureLevel", true));
		entityConfigRepository
				.register(create(modelManager, new Key<>(PhysicalDimension.class), "PhysDimension", false));
		entityConfigRepository.register(create(modelManager, new Key<>(User.class), "User", false));
		entityConfigRepository.register(create(modelManager, new Key<>(Measurement.class), "MeaResult", false));
		entityConfigRepository.register(create(modelManager, new Key<>(ChannelGroup.class), "SubMatrix", false));

		// Unit
		EntityConfig<Unit> unitConfig = create(modelManager, new Key<>(Unit.class), "Unit", false);
		unitConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(PhysicalDimension.class)));
		entityConfigRepository.register(unitConfig);

		// Quantity
		EntityConfig<Quantity> quantityConfig = create(modelManager, new Key<>(Quantity.class), "Quantity", false);
		quantityConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(Unit.class)));
		entityConfigRepository.register(quantityConfig);

		// Channel
		EntityConfig<Channel> channelConfig = create(modelManager, new Key<>(Channel.class), "MeaQuantity", false);
		channelConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(Unit.class)));
		channelConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(Quantity.class)));
		entityConfigRepository.register(channelConfig);

		// ValueList
		EntityConfig<ValueListValue> valueListValueConfig = create(modelManager, new Key<>(ValueListValue.class),
				"ValueListValue", true);
		valueListValueConfig.setComparator(Sortable.COMPARATOR);
		EntityConfig<ValueList> valueListConfig = create(modelManager, new Key<>(ValueList.class), "ValueList", true);
		valueListConfig.addChild(valueListValueConfig);
		entityConfigRepository.register(valueListConfig);

		// ParameterSet
		EntityConfig<Parameter> parameterConfig = create(modelManager, new Key<>(Parameter.class), "ResultParameter",
				true);
		parameterConfig.addOptional(entityConfigRepository.findRoot(new Key<>(Unit.class)));
		EntityConfig<ParameterSet> parameterSetConfig = create(modelManager, new Key<>(ParameterSet.class),
				"ResultParameterSet", true);
		parameterSetConfig.addChild(parameterConfig);
		entityConfigRepository.register(parameterSetConfig);

		// CatalogComponents
		registerCatalogComponent(modelManager, ContextType.UNITUNDERTEST);
		registerCatalogComponent(modelManager, ContextType.TESTSEQUENCE);
		registerCatalogComponent(modelManager, ContextType.TESTEQUIPMENT);

		// TemplateRoots
		registerTemplateRoot(modelManager, ContextType.UNITUNDERTEST);
		registerTemplateRoot(modelManager, ContextType.TESTSEQUENCE);
		registerTemplateRoot(modelManager, ContextType.TESTEQUIPMENT);

		// TemplateTestStep
		EntityConfig<TemplateTestStep> templateTestStepConfig = create(modelManager, new Key<>(TemplateTestStep.class),
				"TplTestStep", true);
		templateTestStepConfig
				.addOptional(entityConfigRepository.findRoot(new Key<>(TemplateRoot.class, ContextType.UNITUNDERTEST)));
		templateTestStepConfig
				.addOptional(entityConfigRepository.findRoot(new Key<>(TemplateRoot.class, ContextType.TESTSEQUENCE)));
		templateTestStepConfig
				.addOptional(entityConfigRepository.findRoot(new Key<>(TemplateRoot.class, ContextType.TESTEQUIPMENT)));
		templateTestStepConfig.setComparator(Versionable.COMPARATOR);
		entityConfigRepository.register(templateTestStepConfig);

		// Status
		entityConfigRepository.register(create(modelManager, new Key<>(Status.class), "Status", false));

		// ProjectDomain
		entityConfigRepository.register(create(modelManager, new Key<>(ProjectDomain.class), "ProjectDomain", false));

		// Domain
		entityConfigRepository.register(create(modelManager, new Key<>(Domain.class), "Domain", false));

		// Classification
		EntityConfig<Classification> classificationConfig = create(modelManager, new Key<>(Classification.class),
				"Classification", false);
		classificationConfig.addOptional(entityConfigRepository.findRoot(new Key<>(Status.class)));
		classificationConfig.addOptional(entityConfigRepository.findRoot(new Key<>(ProjectDomain.class)));
		classificationConfig.addOptional(entityConfigRepository.findRoot(new Key<>(Domain.class)));
		entityConfigRepository.register(classificationConfig);

		// TestStep
		EntityConfig<TestStep> testStepConfig = create(modelManager, new Key<>(TestStep.class), "TestStep", true);
		// testStepConfig.addMandatory(entityConfigRepository.findRoot(new
		// Key<>(Status.class, TestStep.class)));
		testStepConfig.addOptional(entityConfigRepository.findRoot(new Key<>(TemplateTestStep.class)));
		testStepConfig.addOptional(entityConfigRepository.findRoot(new Key<>(Classification.class)));
		testStepConfig.setComparator(Sortable.COMPARATOR);
		entityConfigRepository.register(testStepConfig);

		// TemplateTest
		EntityConfig<TemplateTestStepUsage> templateTestStepUsageConfig = create(modelManager,
				new Key<>(TemplateTestStepUsage.class), "TplTestStepUsage", true);
		templateTestStepUsageConfig.addMandatory(templateTestStepConfig);
		templateTestStepUsageConfig.setComparator(Sortable.COMPARATOR);
		EntityConfig<TemplateTest> templateTestConfig = create(modelManager, new Key<>(TemplateTest.class), "TplTest",
				true);
		templateTestConfig.addChild(templateTestStepUsageConfig);
		templateTestConfig.setComparator(Versionable.COMPARATOR);
		entityConfigRepository.register(templateTestConfig);

		// Status Test
		// TODO check MIME type genration
		// entityConfigRepository.register(create(new Key<>(Status.class,
		// Test.class), "StatusTest", true));

		// Test
		EntityConfig<Test> testConfig = create(modelManager, new Key<>(Test.class), "Test", true);
		testConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(User.class)));
		// testConfig.addMandatory(entityConfigRepository.findRoot(new
		// Key<>(Status.class, Test.class)));
		testConfig.addOptional(entityConfigRepository.findRoot(new Key<>(TemplateTest.class)));
		testConfig.addOptional(entityConfigRepository.findRoot(new Key<>(Classification.class)));
		entityConfigRepository.register(testConfig);

		// ContextRoots
		registerContextRoot(modelManager, ContextType.UNITUNDERTEST);
		registerContextRoot(modelManager, ContextType.TESTSEQUENCE);
		registerContextRoot(modelManager, ContextType.TESTEQUIPMENT);

		LOGGER.debug("Entity configurations loaded in {} ms.", System.currentTimeMillis() - start);
		return entityConfigRepository;
	}

	/**
	 * Loads the {@link EntityConfig}s required for {@link ContextRoot} with given
	 * {@link ContextType}.
	 *
	 * @param contextType The {@code ContextType}.
	 */
	private void registerContextRoot(ODSModelManager modelManager, ContextType contextType) {
		EntityConfig<ContextRoot> contextRootConfig = create(modelManager, new Key<>(ContextRoot.class, contextType),
				ODSUtils.CONTEXTTYPES.get(contextType), true);
		contextRootConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(TemplateRoot.class, contextType)));
		for (Relation contextComponentRelation : contextRootConfig.getEntityType().getChildRelations()) {
			EntityType contextComponentEntityType = contextComponentRelation.getTarget();
			EntityConfig<ContextComponent> contextComponentConfig = create(modelManager,
					new Key<>(ContextComponent.class, contextType), contextComponentEntityType.getName(), true);
			contextComponentConfig
					.addInherited(entityConfigRepository.findImplicit(new Key<>(TemplateComponent.class, contextType)));
			contextRootConfig.addChild(contextComponentConfig);
			if (contextType.isTestEquipment()) {
				for (Relation contextSensorRelation : contextComponentEntityType.getChildRelations()) {
					EntityType contextSensorEntityType = contextSensorRelation.getTarget();
					EntityConfig<ContextSensor> contextSensorConfig = create(modelManager,
							new Key<>(ContextSensor.class), contextSensorEntityType.getName(), true);
					contextSensorConfig
							.addInherited(entityConfigRepository.findImplicit(new Key<>(TemplateSensor.class)));
					contextComponentConfig.addChild(contextSensorConfig);
				}
			}
		}
		entityConfigRepository.register(contextRootConfig);
	}

	/**
	 * Loads the {@link EntityConfig}s required for {@link TemplateRoot} with given
	 * {@link ContextType}.
	 *
	 * @param contextType The {@code ContextType}.
	 */
	private void registerTemplateRoot(ODSModelManager modelManager, ContextType contextType) {
		String odsName = ODSUtils.CONTEXTTYPES.get(contextType);
		EntityConfig<TemplateAttribute> templateAttributeConfig = create(modelManager,
				new Key<>(TemplateAttribute.class, contextType), "Tpl" + odsName + "Attr", true);
		templateAttributeConfig
				.addInherited(entityConfigRepository.findImplicit(new Key<>(CatalogAttribute.class, contextType)));
		templateAttributeConfig.setComparator(TemplateAttribute.COMPARATOR);
		EntityConfig<TemplateComponent> templateComponentConfig = create(modelManager,
				new Key<>(TemplateComponent.class, contextType), "Tpl" + odsName + "Comp", true);
		templateComponentConfig.addChild(templateAttributeConfig);
		templateComponentConfig
				.addMandatory(entityConfigRepository.findRoot(new Key<>(CatalogComponent.class, contextType)));
		templateComponentConfig.addChild(templateComponentConfig);
		templateComponentConfig.setComparator(Sortable.COMPARATOR);
		if (contextType.isTestEquipment()) {
			EntityConfig<TemplateAttribute> templateSensorAttributeConfig = create(modelManager,
					new Key<>(TemplateAttribute.class), "TplSensorAttr", true);
			templateSensorAttributeConfig.setComparator(TemplateAttribute.COMPARATOR);
			templateSensorAttributeConfig
					.addInherited(entityConfigRepository.findImplicit(new Key<>(CatalogAttribute.class)));
			EntityConfig<TemplateSensor> templateSensorConfig = create(modelManager, new Key<>(TemplateSensor.class),
					"TplSensor", true);
			templateSensorConfig.addChild(templateSensorAttributeConfig);
			templateSensorConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(Quantity.class)));
			templateSensorConfig.addInherited(entityConfigRepository.findImplicit(new Key<>(CatalogSensor.class)));
			templateSensorConfig.setComparator(Sortable.COMPARATOR);
			templateComponentConfig.addChild(templateSensorConfig);
		}
		EntityConfig<TemplateRoot> templateRootConfig = create(modelManager, new Key<>(TemplateRoot.class, contextType),
				"Tpl" + odsName + "Root", true);
		templateRootConfig.addChild(templateComponentConfig);
		templateRootConfig.setComparator(Versionable.COMPARATOR);
		entityConfigRepository.register(templateRootConfig);
	}

	/**
	 * Loads the {@link EntityConfig}s required for {@link CatalogComponent} with
	 * given {@link ContextType}.
	 *
	 * @param contextType The {@code ContextType}.
	 */
	private void registerCatalogComponent(ODSModelManager modelManager, ContextType contextType) {
		String odsName = ODSUtils.CONTEXTTYPES.get(contextType);
		EntityConfig<CatalogAttribute> catalogAttributeConfig = create(modelManager,
				new Key<>(CatalogAttribute.class, contextType), "Cat" + odsName + "Attr", true);
		catalogAttributeConfig.addOptional(entityConfigRepository.findRoot(new Key<>(ValueList.class)));
		catalogAttributeConfig.setComparator(Sortable.COMPARATOR);
		EntityConfig<CatalogComponent> catalogComponentConfig = create(modelManager,
				new Key<>(CatalogComponent.class, contextType), "Cat" + odsName + "Comp", true);
		catalogComponentConfig.addChild(catalogAttributeConfig);
		if (contextType.isTestEquipment()) {
			EntityConfig<CatalogAttribute> catalogSensorAttributeConfig = create(modelManager,
					new Key<>(CatalogAttribute.class), "CatSensorAttr", true);
			catalogSensorAttributeConfig.addOptional(entityConfigRepository.findRoot(new Key<>(ValueList.class)));
			EntityConfig<CatalogSensor> catalogSensorConfig = create(modelManager, new Key<>(CatalogSensor.class),
					"CatSensor", true);
			catalogSensorConfig.addChild(catalogSensorAttributeConfig);
			catalogComponentConfig.addChild(catalogSensorConfig);
		}
		entityConfigRepository.register(catalogComponentConfig);
	}

	/**
	 * Creates a new {@link EntityConfig}.
	 *
	 * @param            <T> The entity type.
	 * @param key        Used as identifier.
	 * @param typeName   Name of the associated {@link EntityType}.
	 * @param appendName Flag indicates whether to append the entity types base name
	 *                   to the MIME type.
	 * @return The created {@code EntityConfig} is returned.
	 */
	private <T extends Entity> EntityConfig<T> create(ODSModelManager modelManager, Key<T> key, String typeName,
			boolean appendName) {
		EntityConfig<T> entityConfig = new EntityConfig<>(key);
		ODSEntityType entityType = (ODSEntityType) modelManager.getEntityType(typeName);
		entityConfig.setEntityType(entityType);
		entityConfig.setMimeType(buildDefaultMimeType(entityType, appendName));
		return entityConfig;
	}

	/**
	 * Creates a default MIME type for given {@link EntityType}.
	 *
	 * @param entityType The {@code EntityType}.
	 * @param appendName Flag indicates whether to append the entity types base name
	 *                   to the MIME type.
	 * @return The created MIME type {@code String} is returned.
	 */
	private String buildDefaultMimeType(ODSEntityType entityType, boolean appendName) {
		StringBuilder sb = new StringBuilder();
		sb.append("application/x-asam.");
		sb.append(entityType.getBaseName().toLowerCase(Locale.ROOT));
		if (appendName) {
			sb.append('.').append(entityType.getName().toLowerCase(Locale.ROOT));
		}
		return sb.toString();
	}
}
