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

import fr.gouv.culture.sdx.exception.SDXException;
import fr.gouv.culture.sdx.framework.Framework;
import fr.gouv.culture.sdx.pipeline.Pipeline;
import fr.gouv.culture.sdx.user.User;
import fr.gouv.culture.sdx.utils.AbstractSdxObject;
import fr.gouv.culture.sdx.utils.constants.Node;
import org.apache.avalon.framework.parameters.Parameters;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

/**
 * Parameters governing the way documents are added to a document base.
 *
 * <p>
 * This class contains some basic information needed when a document
 * is added to a document base. Information such as whether the document
 * must replace another document with the same id or if attached documents
 * should be handled or not.
 */
public class IndexParameters extends AbstractSdxObject {

    public static final String CLASS_NAME_SUFFIX = "IndexParameters";
    /** String representations of the SAME_ID parameter. */
    private static final String[] SAME_ID_STRINGS = {"replace", "error", "ignore"};

    /**String representation of the attribute name "sameId". */
    private static final String ATTRIBUTE_SAME_ID = "sameId";

    /**String representation of the attribute name "handleAttachedDocuments". */
    private static final String ATTRIBUTE_HANDLE_ATTACHED_DOCUMENTS = "handleAttachedDocuments";

    /**String representation of the attribute name "handleTabularData". */
    private static final String ATTRIBUTE_HANDLE_TABULAR_DATA = "handleTabularData";

    /**Parameters for a Pipline*/
    private Parameters pipelineParams = null;

    /** Replaces a document with the same id. */
    public static final int SAME_ID_REPLACE = 0;

    /** Throws an error if a document with same id exists. */
    public static final int SAME_ID_ERROR = 1;

    /** Silently ignore a document if one with the same id already exists. */
    public static final int SAME_ID_IGNORE = 2;

    /** The 'same id' parameter, defaults to indicating replacement of documents. */
    private int sameId = SAME_ID_REPLACE;

    public static final int SAME_ID_REFRESH_SHARED_DOCUMENT = 6;

    /** Refresh the physical attached document if one with the same id already exists. */
    protected int attachedDocumentSameId = SAME_ID_REFRESH_SHARED_DOCUMENT;

    /** Refresh the sub document if one with the same id already exists. */
    protected int subDocumentSameId = SAME_ID_REFRESH_SHARED_DOCUMENT;

    /** The 'handle attached documents' parameter. */
    private boolean handleAttachedDocuments = true;

    /** The 'handle tabular data' parameter. */
    private boolean handleTabularData = true;

    /**A parameter for saving the original document*/
    private boolean saveOriginalDocument = true;//Defaulted

    /**The sendIndexation events parameter indicating that stats events are only desired after indexation*/
    public static final int SEND_STATS_EVENTS = 3;

    /**The sendIndexation events parameter indicating that error and stats events are only desired after indexation*/
    public static final int SEND_ERRORS_EVENTS = 4;

    /**The sendIndexation events parameter indicating ALL events are desired after indexation*/
    public static final int SEND_ALL_EVENTS = 5;

    /**The sendIndexation events parameter indicating desired events after indexation*/
    private int sendIndexationEvents = SEND_ERRORS_EVENTS;//Defaulted

    /**The user who starts the indexation process with these parameters*/
    private User user;

    /**The desired indexation pipeline*/
    private Pipeline pipe;

    /**The maximum number of documents to be indexed at one time during at batch operation*/
    private int batchMax = 25;

    /**
     * Creates parameters with default values.
     * <p>
     * These values are :
     * <ul>
     * <li>Documents with same id are replaced
     * <li>Attached documents are handled
     * <li>Tabular values are handled
     * </ul>
     */
    public IndexParameters() {
        // Do nothing, default values are already set
    }

    /**
     * Creates parameters with a given replace value.
     * <p>
     * Other parameters are the defaults.
     *
     * @param   sameId     A code to tell how documents with same ids are handled.
     */
    public IndexParameters(int sameId) {
        this.sameId = sameId;
        // Other default are OK
    }

    /**
     * Creates parameters with specified values.
     *
     * @param   sameId                      A code to tell how documents with same ids are handled.
     * @param   handleAttachedDocuments     Whether to handle attached documents or not.
     * @param   handleTabularData           Whether to handle tabular data or not.
     */
    public IndexParameters(int sameId, boolean handleAttachedDocuments, boolean handleTabularData) {
        this.sameId = sameId;
        this.handleAttachedDocuments = handleAttachedDocuments;
        this.handleTabularData = handleTabularData;
    }

    public void setSameId(int sameId) {
        this.sameId = sameId;
    }

    /**
     * Returns a code that says how documents with same ids are handled.
     */
    public int handleSameId() {
        return this.sameId;
    }

    public void setAttachedDocumentSameId(int attachedDocumentSameId) {
        this.attachedDocumentSameId = attachedDocumentSameId;
    }

    /**
     * Returns a code that says how documents with same ids are handled.
     */
    public int handleAttachedDocumentSameId() {
        return this.attachedDocumentSameId;
    }

    public void setSubDocumentSameId(int subDocumentSameId) {
        this.subDocumentSameId = subDocumentSameId;
    }

    /**
     * Returns a code that says how documents with same ids are handled.
     */
    public int handleSubDocumentSameId() {
        return this.subDocumentSameId;
    }

    /**
     * Returns whether attached documents must be handled.
     */
    public boolean handleAttachedDocuments() {
        return this.handleAttachedDocuments;
    }

    /**
     * Returns whether tabular data must be handled.
     */
    public boolean handleTabularData() {
        return this.handleTabularData;
    }

    /**
     * Sends an XML representation of these parameters.
     *
     * @param   handler     The handler where to send the events.
     */
    public void toSAX(ContentHandler handler) throws SAXException {
        if (handler != null) {
            AttributesImpl atts = new AttributesImpl();
            atts.addAttribute("", ATTRIBUTE_SAME_ID, ATTRIBUTE_SAME_ID, Node.Type.CDATA, getSameIdString());
            atts.addAttribute("", ATTRIBUTE_HANDLE_ATTACHED_DOCUMENTS, ATTRIBUTE_HANDLE_ATTACHED_DOCUMENTS, Node.Type.CDATA, getHandleAttachedDocumentsString());
            atts.addAttribute("", ATTRIBUTE_HANDLE_TABULAR_DATA, ATTRIBUTE_HANDLE_TABULAR_DATA, Node.Type.CDATA, getHandleTabularDataString());
            handler.startElement(Framework.SDXNamespaceURI, Node.Name.PARAMETERS, Framework.SDXNamespacePrefix + ":" + Node.Name.PARAMETERS, atts);
        }
    }

    /**
     * Returns a string representation of the sameId parameter.
     */
    private String getSameIdString() {
        return SAME_ID_STRINGS[handleSameId()];
    }

    /**
     * Returns a string representation of the handleAttachedDocuments parameter.
     */
    private String getHandleAttachedDocumentsString() {
        return String.valueOf(handleAttachedDocuments());
    }

    /**
     * Returns a String representation of the handleTabularData parameter.
     */
    private String getHandleTabularDataString() {
        return String.valueOf(handleTabularData());
    }

    /**Sets the parameters for the pipeline
     *
     * @return The parameters for the pipeline, null if none set
     */
    public Parameters getPipelineParams() {
        return pipelineParams;
    }

    /**Set's the parameters for the pipeline
     *
     * @param pipelineParams    The pipeline parameters
     */
    public void setPipelineParams(Parameters pipelineParams) {
        this.pipelineParams = pipelineParams;
    }

    /**Gets the user for this indexation parameter
     *
     * @return   The sdx user
     */
    public User getUser() {
        return user;
    }

    /**Sets the user for this indexation parameter
     *
     * @param user  The user
     */
    public void setUser(User user) throws SDXException {
        this.user = user;
    }

    /**Gets the desired indexation pipeline
     *
     * @return
     */
    public Pipeline getPipeline() {
        return pipe;
    }

    /**Sets the desired indexation pipeline
     *
     * @param pipe  The desired Pipeline for indexation
     */
    public void setPipeline(Pipeline pipe) {
        this.pipe = pipe;
    }

    /**Returns the property of this object indicating
     * the maximum number of documents to index from a
     * batch at one time (default is 25)
     *
     * @return The number of documents per batch
     */
    public int getBatchMax() {
        return batchMax;
    }

    /**Sets the property of this object indicating
     * the maximum number of documents to index from a
     * batch at one time (default is 25)
     */
    public void setBatchMax(int batchMax) {
        this.batchMax = batchMax;
    }

    public boolean isSaveOriginalDocument() {
        return saveOriginalDocument;
    }

    public void setSaveOriginalDocument(boolean saveOriginalDocument) {
        this.saveOriginalDocument = saveOriginalDocument;
    }

    public int getSendIndexationEvents() {
        return sendIndexationEvents;
    }

    public void setSendIndexationEvents(int sendIndexationEvents) {
        this.sendIndexationEvents = sendIndexationEvents;
    }

    protected String getClassNameSuffix() {
        return IndexParameters.CLASS_NAME_SUFFIX;
    }

	/* (non-Javadoc)
	 * @see fr.gouv.culture.sdx.utils.AbstractSdxObject#initToSax()
	 */
	protected boolean initToSax() {
		return true;
	}

	/**Init the LinkedHashMap _xmlizable_volatile_objects with the objects in order to describ them in XML
	 * Some objects need to be refresh each time a toSAX is called*/
	protected void initVolatileObjectsToSax() {}
}
