/********************************************************************************
 * 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.atfxadapter;

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.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.Pool;
import org.eclipse.mdm.api.dflt.model.Project;
import org.eclipse.mdm.api.odsadapter.lookup.config.DefaultEntityConfigRepositoryLoader;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig.Key;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfigRepository;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfigRepositoryLoader;
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 ATFXEntityConfigRepositoryLoader implements EntityConfigRepositoryLoader {

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

	EntityConfigRepository entityConfigRepository;

	private final boolean includeCatalog;

	public ATFXEntityConfigRepositoryLoader(boolean includeCatalog) {
		this.includeCatalog = includeCatalog;
	}

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

		entityConfigRepository = new EntityConfigRepository();

		// 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<>(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);

		// 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);

		if (includeCatalog) {
			// CatalogComponents
			registerCatalogComponent(modelManager, ContextType.UNITUNDERTEST);
			registerCatalogComponent(modelManager, ContextType.TESTSEQUENCE);
			registerCatalogComponent(modelManager, ContextType.TESTEQUIPMENT);
		}

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

		// Test
		EntityConfig<Test> testConfig = create(modelManager, new Key<>(Test.class), "Test", true);
		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);
		for (Relation contextComponentRelation : contextRootConfig.getEntityType().getChildRelations()) {
			EntityType contextComponentEntityType = contextComponentRelation.getTarget();
			EntityConfig<ContextComponent> contextComponentConfig = create(modelManager,
					new Key<>(ContextComponent.class, contextType), contextComponentEntityType.getName(), true);
			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);
					contextComponentConfig.addChild(contextSensorConfig);
				}
			}
		}
		entityConfigRepository.register(contextRootConfig);
	}

	/**
	 * 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;
	}

	/**
	 * 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.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);
			EntityConfig<CatalogSensor> catalogSensorConfig = create(modelManager, new Key<>(CatalogSensor.class),
					"CatSensor", true);
			catalogSensorConfig.addChild(catalogSensorAttributeConfig);
			catalogComponentConfig.addChild(catalogSensorConfig);
		}
		entityConfigRepository.register(catalogComponentConfig);
	}

	/**
	 * 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();
	}
}
