package org.gcube.application.geoportal.service.engine.mongo;

import java.io.IOException;

import org.bson.Document;
import org.gcube.application.cms.implementations.faults.DeletionException;
import org.gcube.application.cms.implementations.faults.InvalidLockException;
import org.gcube.application.cms.implementations.faults.InvalidUserRoleException;
import org.gcube.application.cms.implementations.faults.ProjectLockedException;
import org.gcube.application.cms.implementations.faults.ProjectNotFoundException;
import org.gcube.application.cms.implementations.faults.RegistrationException;
import org.gcube.application.cms.implementations.faults.UnauthorizedAccess;
import org.gcube.application.cms.plugins.faults.EventException;
import org.gcube.application.cms.plugins.faults.InsufficientPrivileges;
import org.gcube.application.cms.plugins.faults.StepException;
import org.gcube.application.geoportal.common.faults.StorageException;
import org.gcube.application.geoportal.common.model.configuration.Configuration;
import org.gcube.application.geoportal.common.model.document.access.Access;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.application.geoportal.common.model.rest.QueryRequest;
import org.gcube.application.geoportal.common.model.rest.RegisterFileSetRequest;
import org.gcube.common.storagehub.model.exceptions.StorageHubException;

import com.fasterxml.jackson.core.JsonProcessingException;

/**
 * The Interface MongoManagerI.
 * 
 * @author Fabio Sinibaldi
 * @author maintainer: Francesco Mangiacrapa at ISTI-CNR
 *         francesco.mangiacrapa@isti.cnr.it
 * 
 *         Apr 18, 2023
 * @param <T> the generic type
 */
public interface MongoManagerI<T> {

	// create

	/**
	 * Register new.
	 *
	 * @param toRegister the to register
	 * @return the t
	 * @throws IOException              Signals that an I/O exception has occurred.
	 * @throws StepException            the step exception
	 * @throws EventException           the event exception
	 * @throws InvalidUserRoleException the invalid user role exception
	 */
	public T registerNew(Document toRegister)
			throws IOException, StepException, EventException, InvalidUserRoleException;

	/**
	 * Update.
	 *
	 * @param id            the id
	 * @param toSetDocument the to set document
	 * @return the t
	 * @throws IOException              Signals that an I/O exception has occurred.
	 * @throws StepException            the step exception
	 * @throws EventException           the event exception
	 * @throws ProjectLockedException   the project locked exception
	 * @throws ProjectNotFoundException the project not found exception
	 * @throws InvalidLockException     the invalid lock exception
	 * @throws InvalidUserRoleException the invalid user role exception
	 * @throws UnauthorizedAccess       the unauthorized access
	 */
	// update
	public T update(String id, Document toSetDocument)
			throws IOException, StepException, EventException, ProjectLockedException, ProjectNotFoundException,
			InvalidLockException, InvalidUserRoleException, UnauthorizedAccess;

	/**
	 * Patch.
	 *
	 * @param id    the id
	 * @param toSet the to set
	 * @return the t
	 * @throws IOException              Signals that an I/O exception has occurred.
	 * @throws EventException           the event exception
	 * @throws ProjectLockedException   the project locked exception
	 * @throws ProjectNotFoundException the project not found exception
	 * @throws InvalidLockException     the invalid lock exception
	 * @throws InvalidUserRoleException the invalid user role exception
	 * @throws UnauthorizedAccess       the unauthorized access
	 */
	// patch
	public T patch(String id, Document toSet) throws IOException, EventException, ProjectLockedException,
			ProjectNotFoundException, InvalidLockException, InvalidUserRoleException, UnauthorizedAccess;

	/**
	 * Sets the relation.
	 *
	 * @param id        the id
	 * @param relation  the relation
	 * @param targetUCD the target UCD
	 * @param targetId  the target id
	 * @return the t
	 * @throws IOException              Signals that an I/O exception has occurred.
	 * @throws StepException            the step exception
	 * @throws EventException           the event exception
	 * @throws ProjectLockedException   the project locked exception
	 * @throws ProjectNotFoundException the project not found exception
	 * @throws InvalidLockException     the invalid lock exception
	 * @throws InvalidUserRoleException the invalid user role exception
	 * @throws UnauthorizedAccess       the unauthorized access
	 * @throws RegistrationException    the registration exception
	 * @throws ConfigurationException   the configuration exception
	 */
	public T setRelation(String id, String relation, String targetUCD, String targetId) throws IOException,
			StepException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException,
			InvalidUserRoleException, UnauthorizedAccess, RegistrationException, ConfigurationException;

	/**
	 * Delete relation.
	 *
	 * @param id        the id
	 * @param relation  the relation
	 * @param targetUCD the target UCD
	 * @param targetId  the target id
	 * @return the t
	 * @throws IOException              Signals that an I/O exception has occurred.
	 * @throws StepException            the step exception
	 * @throws EventException           the event exception
	 * @throws ProjectLockedException   the project locked exception
	 * @throws ProjectNotFoundException the project not found exception
	 * @throws InvalidLockException     the invalid lock exception
	 * @throws InvalidUserRoleException the invalid user role exception
	 * @throws UnauthorizedAccess       the unauthorized access
	 * @throws RegistrationException    the registration exception
	 * @throws ConfigurationException   the configuration exception
	 */
	public T deleteRelation(String id, String relation, String targetUCD, String targetId) throws IOException,
			StepException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException,
			InvalidUserRoleException, UnauthorizedAccess, RegistrationException, ConfigurationException;

	// delete

	/**
	 * Delete.
	 *
	 * @param id    the id
	 * @param force the force
	 * @throws DeletionException        the deletion exception
	 * @throws InvalidUserRoleException the invalid user role exception
	 * @throws ProjectLockedException   the project locked exception
	 * @throws ProjectNotFoundException the project not found exception
	 * @throws UnauthorizedAccess       the unauthorized access
	 * @throws JsonProcessingException  the json processing exception
	 * @throws InvalidLockException     the invalid lock exception
	 */
	public void delete(String id, boolean force)
			throws DeletionException, InvalidUserRoleException, ProjectLockedException, ProjectNotFoundException,
			UnauthorizedAccess, JsonProcessingException, InvalidLockException;

	// get By ID

	/**
	 * Gets the by ID.
	 *
	 * @param id the id
	 * @return the by ID
	 * @throws IOException              Signals that an I/O exception has occurred.
	 * @throws ProjectNotFoundException the project not found exception
	 * @throws InvalidUserRoleException the invalid user role exception
	 * @throws UnauthorizedAccess       the unauthorized access
	 */
	public T getByID(String id)
			throws IOException, ProjectNotFoundException, InvalidUserRoleException, UnauthorizedAccess;

	// query

	/**
	 * Query.
	 *
	 * @param request the request
	 * @return the iterable
	 * @throws InvalidUserRoleException the invalid user role exception
	 */
	public Iterable<Document> query(QueryRequest request) throws InvalidUserRoleException;

	/**
	 * Filter.
	 *
	 * @param request the request
	 * @return the iterable
	 * @throws InvalidUserRoleException the invalid user role exception
	 */
	public Iterable<T> filter(QueryRequest request) throws InvalidUserRoleException;

	/**
	 * Perform step.
	 *
	 * @param id      the id
	 * @param step    the step
	 * @param options the options
	 * @return the t
	 * @throws IOException              Signals that an I/O exception has occurred.
	 * @throws StepException            the step exception
	 * @throws ProjectLockedException   the project locked exception
	 * @throws ProjectNotFoundException the project not found exception
	 * @throws InvalidLockException     the invalid lock exception
	 * @throws InvalidUserRoleException the invalid user role exception
	 * @throws UnauthorizedAccess       the unauthorized access
	 * @throws ConfigurationException   the configuration exception
	 * @throws InsufficientPrivileges   the insufficient privileges
	 */
	public T performStep(String id, String step, Document options)
			throws IOException, StepException, ProjectLockedException, ProjectNotFoundException, InvalidLockException,
			InvalidUserRoleException, UnauthorizedAccess, ConfigurationException, InsufficientPrivileges;

	/**
	 * Register file set.
	 *
	 * @param id      the id
	 * @param request the request
	 * @return the t
	 * @throws ConfigurationException   the configuration exception
	 * @throws StorageHubException      the storage hub exception
	 * @throws StorageException         the storage exception
	 * @throws StepException            the step exception
	 * @throws JsonProcessingException  the json processing exception
	 * @throws DeletionException        the deletion exception
	 * @throws EventException           the event exception
	 * @throws ProjectLockedException   the project locked exception
	 * @throws ProjectNotFoundException the project not found exception
	 * @throws InvalidLockException     the invalid lock exception
	 * @throws InvalidUserRoleException the invalid user role exception
	 * @throws UnauthorizedAccess       the unauthorized access
	 */
	public T registerFileSet(String id, RegisterFileSetRequest request)
			throws ConfigurationException, StorageHubException, StorageException, StepException,
			JsonProcessingException, DeletionException, EventException, ProjectLockedException,
			ProjectNotFoundException, InvalidLockException, InvalidUserRoleException, UnauthorizedAccess;

	/**
	 * Delete file set.
	 *
	 * @param id            the id
	 * @param destination   the destination
	 * @param force         the force
	 * @param ignore_errors the ignore errors
	 * @return the t
	 * @throws ConfigurationException   the configuration exception
	 * @throws StorageHubException      the storage hub exception
	 * @throws StorageException         the storage exception
	 * @throws StepException            the step exception
	 * @throws JsonProcessingException  the json processing exception
	 * @throws DeletionException        the deletion exception
	 * @throws EventException           the event exception
	 * @throws ProjectLockedException   the project locked exception
	 * @throws ProjectNotFoundException the project not found exception
	 * @throws InvalidLockException     the invalid lock exception
	 * @throws InvalidUserRoleException the invalid user role exception
	 * @throws UnauthorizedAccess       the unauthorized access
	 */
	public T deleteFileSet(String id, String path, Boolean force, Boolean ignore_errors) throws ConfigurationException,
			StorageHubException, JsonProcessingException, DeletionException, EventException, ProjectLockedException,
			ProjectNotFoundException, InvalidLockException, InvalidUserRoleException, UnauthorizedAccess;

	/**
	 * Force unlock.
	 *
	 * @param id the id
	 * @return the t
	 * @throws InvalidUserRoleException the invalid user role exception
	 * @throws ProjectNotFoundException the project not found exception
	 * @throws UnauthorizedAccess       the unauthorized access
	 * @throws JsonProcessingException  the json processing exception
	 * @throws InvalidLockException     the invalid lock exception
	 */
	public T forceUnlock(String id) throws InvalidUserRoleException, ProjectNotFoundException, UnauthorizedAccess,
			JsonProcessingException, InvalidLockException;

	/**
	 * Sets the access policy.
	 *
	 * @param id     the id
	 * @param access the access
	 * @return the t
	 * @throws InvalidUserRoleException the invalid user role exception
	 * @throws ProjectLockedException   the project locked exception
	 * @throws ProjectNotFoundException the project not found exception
	 * @throws UnauthorizedAccess       the unauthorized access
	 * @throws JsonProcessingException  the json processing exception
	 * @throws InvalidLockException     the invalid lock exception
	 * @throws EventException           the event exception
	 */
	public T setAccessPolicy(String id, Access access) throws InvalidUserRoleException, ProjectLockedException,
			ProjectNotFoundException, UnauthorizedAccess, JsonProcessingException, InvalidLockException, EventException;

	/**
	 * Gets the configuration.
	 *
	 * @return the configuration
	 * @throws ConfigurationException the configuration exception
	 */
	public Configuration getConfiguration() throws ConfigurationException;

}
