/*
Copyright (C) 2000-2010  Ministere de la culture et de la communication (France), AJLSM
See LICENCE file
*/
package fr.gouv.culture.sdx.documentbase;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;

//import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.xml.XMLConsumer;
import org.apache.excalibur.source.SourceValidity;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;

import fr.gouv.culture.oai.OAIHarvester;
import fr.gouv.culture.oai.OAIRepository;
import fr.gouv.culture.sdx.document.Document;
import fr.gouv.culture.sdx.document.IndexableDocument;
import fr.gouv.culture.sdx.document.ParsableDocument;
import fr.gouv.culture.sdx.exception.SDXException;
import fr.gouv.culture.sdx.pipeline.Pipeline;
import fr.gouv.culture.sdx.repository.Repository;
import fr.gouv.culture.sdx.search.Searchable;
import fr.gouv.culture.sdx.utils.SdxObject;
import fr.gouv.culture.sdx.utils.save.Saveable;

/**
 * A location where documents are indexed, stored, searched and retrieved.
 */
//TODORefactor2.2: the searchable interface extension ties us to Lucene

public interface DocumentBase extends SdxObject, Searchable, Saveable {

    interface ConfigurationNode {
        /** The element used to define the indexation pipelines. */
        String INDEX = "index";
        /** The element used to define an indexation pipeline. */
        String PIPELINE = "pipeline";
        /** The element used to define an oai repository. */
        String OAI_REPOSITORY = "oai-repository";
        /** The element used to define an oai harvester. */
        String OAI_HARVESTER = "oai-harvester";
        /** The element used to define the indexation field list. */
        String FIELD_LIST = "fieldList";
    }
    /**************************************************
     Utilities for using concrete descendant class names
     **************************************************/

    /** The document base's package name (including trailing separator "."). */
    public static final String PACKAGE_QUALNAME = "fr.gouv.culture.sdx.documentbase.";
    /** The document base's class name suffix. */
    public static final String CLASS_NAME_SUFFIX = "DocumentBase"; //So  : "fr.gouv.culture.sdx.documentbase.WhateverYouLikeDocumentBase"

    /**
     * Initializes the document base.
     *
     * <p>
     * This method must be called after the super.getLog() has been set and the configuration
     * done.
     */
    public void init() throws SDXException, ConfigurationException;

    /**
     * Returns <code>true</code> if this document base is the default in the application.
     */
    public boolean isDefault();
    
    /**
     * Returns the default number of results on page for this DocumentBase.
     * @return 		The default hpp for the DocumentBase
     */
    public int getDefaultHitsPerPage();
    
    /**
     * Returns the default maximum number of results to sort for this DocumentBase.
     * @return 		The default maxsort for the DocumentBase
     */
    public int getDefaultMaxSort();

    /**
     * Returns a repository which is owned by this document base using its id.
     *
     * @param   id      The requested repository's id.
     * @return          The requested repository, or the default repository is the id doesn't match any repository id. TODO : dangerous behaviour IMHO -pb
     */
    public Repository getRepository(String id) throws SDXException;

    /**
     * Returns the default repository for the DocumentBase.
     */
    public Repository getDefaultRepository();

    /** Returns the default indexation pipeline used for indexation in this document base. */
    public Pipeline getIndexationPipeline();

    /**
     * Indexes a document and stores it in a repository.
     *
     * @param   doc             The document to index and add.
     * @param   repository      The repository where the document have to be stored.
     * @param   params          Parameters governing the indexing process.
     * @param   handler         The SAX events consumer that receives informations about the indexing process.
     */
    public void index(IndexableDocument doc, Repository repository, IndexParameters params, ContentHandler handler) throws SDXException, SAXException, ProcessingException;

    /**
     * Indexes documents and stores them in a repository.
     *
     * @param   docs            The documents to index and add.
     * @param   repository      The repository where the documents have to be stored.
     * @param   params          Parameters governing the indexing process.
     * @param   handler         The SAX events consumer that receives informations about the indexing process.
     */
    public void index(IndexableDocument[] docs, Repository repository, IndexParameters params, ContentHandler handler) throws SDXException, SAXException, ProcessingException;

    /**
     * Deletes a document.
     *
     * @param   doc         The id of the document to delete.
     * @param   handler     The SAX events consumer that receives informations about the deletion process.
     */
    public void delete(Document doc, ContentHandler handler) throws SDXException, SAXException, ProcessingException;

    /**
     * Deletes documents.
     *
     * @param   docs        The documents to delete.
     * @param   handler     The SAX events consumer that receives informations about the deletion process.
     */
    public void delete(Document[] docs, ContentHandler handler) throws SDXException, SAXException, ProcessingException;

    /**
     * Sends a document as SAX events.
     *
     * @param   doc             A ParsableDocument, i.e. XMLDocument or HTMLDocument.
     * @param	consumer	A SAX content handler to feed with events.
     * The wrapped contentHandler for including events within an XSP page contentHandler should be created using
     * <code>IncludeXMLConsumer stripper = new IncludeXMLConsumer(xspContentHandler);</code> and then the "stripper" should be passed
     * to this method
     */
    public void getDocument(ParsableDocument doc, XMLConsumer consumer) throws SDXException;

    /**
     * Sends a document as SAX events.
     *
     * @param   doc             A ParsableDocument, i.e. XMLDocument or HTMLDocument.
     * @param	consumer	A SAX content handler to feed with events.
     *@param   docTypeKnown If set to <code>false</code> implementations should attempt to determine the doctyp(see LuceneDocumentBase)
     * The wrapped contentHandler for including events within an XSP page contentHandler should be created using
     * <code>IncludeXMLConsumer stripper = new IncludeXMLConsumer(xspContentHandler);</code> and then the "stripper" should be passed
     * to this method
     */
    public void getDocument(ParsableDocument doc, XMLConsumer consumer, boolean docTypeKnown) throws SDXException;


    /** Supplies the provided output stream with the requested document
     * @param doc	The document.
     * @param os	The output stream.
     * @throws SDXException
     */
    public void getDocument(Document doc, OutputStream os) throws SDXException;

    /** Provides the requested SDX document as an <code>InputStream</code>.
     * @param doc	The document.
     * @return	An input stream.
     * @throws SDXException
     */
    public InputStream getDocument(Document doc) throws SDXException;

    /** Supplies the mimeType for the the document if it exists.
     * otherwise the default mimetype should be returned TODO : dangerous behaviour IMHO -pb
     * @param doc	The document.
     */
    public String getMimeType(Document doc) throws SDXException;
    
    /**Creates an OAIRepository for the documentbase
     *
     * @return
     */
    //FIXME (MP) : deprecated ?
    OAIRepository createOAIRepository() throws ConfigurationException;

    /**Gets the default OAIRepository for the documentbase if one exists
     *
     * @return	OAIRepository
     */
    OAIRepository getOAIRepository();
    
    /**Returns the specified OAI repository
     * @param	repo	String	The repository id
     * @return	OAIRepository
     */
    public OAIRepository getOAIRepository(String repo);
    
    /**
     * Returns the number of OAI repositories managed by this document base
     * @return	The number of OAI repositories as an int
     */
    int getOAIRepositoriesSize();

    /**Gets the AbstractDocumentBaseOAIHarvester for the documentbase if one exists
     *
     * @return OAIHarvester
     */
    OAIHarvester getOAIHarvester();

    /**
     * Returns the last modification date of the document base
     */
    Date lastModificationDate();

    /**
     * Returns the creation date of the document base
     */
    Date creationDate();

    /**
     * Process an optimization of the documentbase.
     * Can be left empty in implementation but must be present.
     * Should be synchronized in implementations...
     */
	public abstract void optimize();

    /**
     * Check the integrity of the documentBase
     */
	public abstract void checkIntegrity();

	/**
	 * Returns a source validity object for this document base (for caching)
	 */
	public SourceValidity getSourceValidity();
	
}
