package com.tandbergtv.metadatamanager;

import java.util.List;

import org.hibernate.Session;

import com.tandbergtv.metadatamanager.exception.InvalidRevisionException;
import com.tandbergtv.metadatamanager.exception.MetadataException;
import com.tandbergtv.metadatamanager.exception.SearchException;
import com.tandbergtv.metadatamanager.model.Asset;
import com.tandbergtv.metadatamanager.model.FieldRevision;
import com.tandbergtv.metadatamanager.model.Relation;
import com.tandbergtv.metadatamanager.specimpl.ttv.TTVId;

/**
 * Internal interface for this version.
 * 
 */
public interface MetadataManagerDAO {

	/**
	 * @param asset
	 *            This is the Asset (Group/Item) as per the TTV Spec.
	 * @return TTV Id
	 * 
	 * Scenarios - - The asset may contain relation(s) to an existing
	 * group/item.
	 */
	TTVId saveAsset(Asset asset) throws MetadataException;
	
	/**
	 * @param id
	 *            The id which uniquely identifies this asset and is known to
	 *            the application making this call. Would the id need to be
	 *            converted to TTV Spec Identifier or any other field?
	 * 
	 * Scenarios: - Single entry for the asset with that id is found. - Search
	 * results in multiple entries (could the versions be same?) for the same
	 * asset. - Multiple assets with the same id found. Is this even possible? -
	 * Asset with that id is not found. - That specific version not found.
	 * 
	 * Search for the asset with the given id and version.
	 * 
	 * @param id
	 * @return The latest version of the Asset if the version is null.
	 */
	Asset getAsset(TTVId id, boolean isForReadOnly) throws SearchException;
	
	Asset getAsset(TTVId id, int revisionNumber, boolean isForReadOnly) throws InvalidRevisionException, SearchException;
	
	/**
	 * All references are removed.
	 * 
	 * Should this be in sync with CMS which holds the content for this asset?
	 * 
	 * @param Id
	 *            TTV Asset Id
	 * 
	 * Scenarios: - Asset with that Id not found. - Asset with Id found. - Asset
	 * is an Item with no relations. - Asset is part of one group - update the
	 * group containing this asset. - Asset is part of multiple groups - update
	 * all groups containing this asset. - Asset has a one-one relation with
	 * another asset - update the other asset's relations.
	 */
	void delete(Asset a) throws SearchException;
	
	/**
	 * Returns the relation between the given owner and target if exists.
	 * If any of the assets were not found a search exception is thrown.  
	 * 
	 * @param owner
	 * @param target
	 * @return
	 * @throws SearchException
	 */
	Relation getRelation(Asset owner, Asset target) throws SearchException;
	
	/**
	 * Return all input field's previous undeleted versions 
	 * e.g. for field(add, delete, revision) field1(1,0,3), return field1(1,0,1), 
	 * field1(1,0,2) and field1(1,0,3) 
	 * @param field
	 * @return
	 */
	List<FieldRevision> getUnDeletedFieldRevsions(FieldRevision field);
	
	/**
	 * @return Returns current session
	 */
	Session getCurrentSession();
}
