package org.eclipse.basyx.components.aas.mongodb;

import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
import org.eclipse.basyx.aas.restapi.api.IAASAPI;
import org.eclipse.basyx.components.configuration.BaSyxMongoDBConfiguration;
import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;

import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;

/**
 * Implements the IAASAPI for a mongoDB backend.
 * 
 * @author espen
 */
public class MongoDBAASAPI implements IAASAPI {
	private static final String DEFAULT_CONFIG_PATH = "mongodb.properties";
	private static final String AASIDPATH = Identifiable.IDENTIFICATION + "." + Identifier.ID;

	protected BaSyxMongoDBConfiguration config;
	protected MongoOperations mongoOps;
	protected String collection;
	protected String aasId;

	/**
	 * Receives the path of the configuration.properties file in it's constructor.
	 * 
	 * @param configFilePath
	 */
	public MongoDBAASAPI(BaSyxMongoDBConfiguration config, String aasId) {
		this.setConfiguration(config);
		this.setAASId(aasId);
	}

	/**
	 * Receives the path of the .properties file in it's constructor from a resource.
	 */
	public MongoDBAASAPI(String resourceConfigPath, String aasId) {
		config = new BaSyxMongoDBConfiguration();
		config.loadFromResource(resourceConfigPath);
		this.setConfiguration(config);
		this.setAASId(aasId);
	}

	/**
	 * Constructor using default sql connections
	 */
	public MongoDBAASAPI(String aasId) {
		this(DEFAULT_CONFIG_PATH, aasId);
	}

	public void setConfiguration(BaSyxMongoDBConfiguration config) {
		this.config = config;
		MongoClient client = MongoClients.create(config.getConnectionUrl());
		this.mongoOps = new MongoTemplate(client, config.getDatabase());
		this.collection = config.getAASCollection();
	}

	/**
	 * Sets the aas id, so that this API points to the aas with aasId. Can be changed
	 * to point to a different aas in the database.
	 * 
	 * @param smId
	 */
	public void setAASId(String aasId) {
		this.aasId = aasId;
	}

	/**
	 * Depending on whether the model is already in the db, this method inserts or replaces the existing data.
	 * The new aas id for this API is taken from the given aas.
	 * 
	 * @param sm
	 */
	public void setAAS(AssetAdministrationShell aas) {
		String id = aas.getIdentification().getId();
		this.setAASId(id);
		
		Query hasId = query(where(AASIDPATH).is(aasId));
		// Try to replace if already present - otherwise: insert it
		Object replaced = mongoOps.findAndReplace(hasId, aas, collection);
		if (replaced == null) {
			mongoOps.insert(aas, collection);
		}
	}

	@Override
	public IAssetAdministrationShell getAAS() {
		Query hasId = query(where(AASIDPATH).is(aasId));
		AssetAdministrationShell aas = mongoOps.findOne(hasId, AssetAdministrationShell.class, collection);
		if (aas == null) {
			throw new ResourceNotFoundException("The AAS " + aasId + " could not be found in the database.");
		}
		// Remove mongoDB-specific map attribute from AASDescriptor
		aas.remove("_id");
		return aas;
	}

	@Override
	public void addSubmodel(IReference submodel) {
		// Get AAS from db
		Query hasId = query(where(AASIDPATH).is(aasId));
		AssetAdministrationShell aas = mongoOps.findOne(hasId, AssetAdministrationShell.class, collection);
		if (aas == null) {
			throw new ResourceNotFoundException("The AAS " + aasId + " could not be found in the database.");
		}
		// Add reference
		aas.addSubmodelReference(submodel);
		// Update db entry
		mongoOps.findAndReplace(hasId, aas, collection);
	}

	@Override
	public void removeSubmodel(String id) {
		// Get AAS from db
		Query hasId = query(where(AASIDPATH).is(aasId));
		AssetAdministrationShell aas = mongoOps.findOne(hasId, AssetAdministrationShell.class, collection);
		if (aas == null) {
			throw new ResourceNotFoundException("The AAS " + aasId + " could not be found in the database.");
		}
		// Remove reference
		Collection<IReference> smReferences = aas.getSubmodelReferences();
		// Reference to submodel could be either by idShort (=> local) or directly via
		// its identifier
		for (Iterator<IReference> iterator = smReferences.iterator(); iterator.hasNext();) {
			IReference ref = iterator.next();
			List<IKey> keys = ref.getKeys();
			IKey lastKey = keys.get(keys.size() - 1);
			String idValue = lastKey.getValue();
			// remove this reference, if the last key points to the submodel
			if (idValue.equals(id)) {
				iterator.remove();
				break;
			}
		}
		// Update db entry
		mongoOps.findAndReplace(hasId, aas, collection);
	}

}
