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

import fr.gouv.culture.sdx.documentbase.DocumentBase;
import fr.gouv.culture.sdx.exception.SDXException;
import fr.gouv.culture.sdx.search.lucene.query.Results;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.xml.sax.InputSource;


public interface SDXThesaurus extends Thesaurus, DocumentBase {
    interface ConfigurationNode {
        /**String representation of a name used in xml configurations*/
        String THESAURI = "thesauri";
        /**String representation of the "thesaurus" attribute name "src". */
        String SRC = "src";
        /**String representation of the element name*/
        String DEPTH = "depth";
        String RELATIONS = "relations";
        String RELATION = "relation";
    }

    /** String representation of the thesarus package name (including trailing separator "."). */
    String PACKAGE_QUALNAME = "fr.gouv.culture.sdx.thesaurus.";
    /** String representation of the thesaurus class name suffix. */
    String CLASS_NAME_SUFFIX = "Thesaurus";


    void init() throws SDXException, ConfigurationException;

    /**
     * Builds a thesaurus from a File.
     *
     * @param   url    The url to the file containing the thesaurus.
     */
    void build(String url) throws SDXException, ConfigurationException;

    /**
     * Builds a thesaurus from a SAX input source.
     *
     * @param   source      The SAX input source where the thesaurus is.
     */
    void build(InputSource source) throws SDXException;

    /**
     * Returns the number of terms in the thesaurus.
     */
    long size();

    /**
     * Saves the contents.
     *
     */
    void save();

    /**
     * Loads a thesaurus in memory (later).
     */
    void load();

    /**
     * Unloads the memory representation of the thesaurus (later).
     */
    void unload();

    /**
     * Adds a document.
     *
     * @param   concept     The document to add.
     */
    void addConcept(Concept concept) throws SDXException;

    /**
     * Adds a group of documents.
     *
     * @param   concepts     The documents to add.
     */
    void addConcepts(Concept[] concepts) throws SDXException;

    /**
     * Remove a document.
     *
     * @param   concept      The document.
     */
    void deleteConcept(Concept concept) throws SDXException;

    /**
     * Remove a group of documents.
     *
     * @param   concepts     The documents.
     *
     */
    void deleteConcepts(Concept[] concepts) throws SDXException;


    /**
     * Searches for concepts.
     *
     * @param   term       The concept term.
     */
    Concept[] search(String term) throws SDXException;


    /**
     * Returns a document using its name.
     *
     * @param   name    The document's name.
     */
    Concept getConceptByName(String name) throws SDXException;

    /**
     * Returns a document using its id.
     *
     * @param   id      The document's id.
     */
    Concept getConceptById(String id) throws SDXException;

    /**Expands a query returning the results of the expanded query
     *
     * @param query The query object which should be expanded using this thesaurus
     * @return A results object of the executed expanded query
     * @throws fr.gouv.culture.sdx.exception.SDXException
     */
    Results expandQuery(fr.gouv.culture.sdx.search.lucene.query.Query query) throws SDXException;

    /**Expands a query returning the results of the expanded query
     *
     * @param query The query object which should be expanded using this thesaurus
     * @param fieldName The name of field on which expansion should take place
     * @return A results object of the executed expanded query
     * @throws fr.gouv.culture.sdx.exception.SDXException
     */
    Results expandQuery(fr.gouv.culture.sdx.search.lucene.query.Query query, String fieldName) throws SDXException;

    /**Expands a query returning the results of the expanded query
     *
     * @param query The query object which should be expanded using this thesaurus
     * @param fieldName The name of field on which expansion should take place
     * @param relation The relation type, for finding terms which should be used to expand the query
     * @param depth    The depth to which a relation should be followed, 0 finds the relation withing the matching concept
     * 1, finds the relation within concept for the matching relation found by the "0 case", etc.
     * @return A results object of the executed expanded query
     * @throws fr.gouv.culture.sdx.exception.SDXException
     */
    Results expandQuery(fr.gouv.culture.sdx.search.lucene.query.Query query, String fieldName, int relation, int depth) throws SDXException;

    /**Expands a query returning the results of the expanded query
     *
     * @param query The query object which should be expanded using this thesaurus
     * @param fieldName The name of field on which expansion should take place
     * @param relations The relation types, for finding terms which should be used to expand the query
     * @param depth    The depth to which a relation should be followed, 0 finds the relation withing the matching concept
     * 1, finds the relation within concept for the matching relation found by the "0 case", etc.     * @return A results object of the executed expanded query
     * @throws fr.gouv.culture.sdx.exception.SDXException
     */
    Results expandQuery(fr.gouv.culture.sdx.search.lucene.query.Query query, String fieldName, int[] relations, int depth) throws SDXException;

    /**Expands a query returning the results of the expanded query
     *
     * @param query The query object which should be expanded using this thesaurus
     * @param fieldName The name of field on which expansion should take place
     * @param relations The relation types, for finding terms which should be used to expand the query
     * @param depth    The depth to which a relation should be followed, 0 finds the relation withing the matching concept
     * 1, finds the relation within concept for the matching relation found by the "0 case", etc.     * @return A results object of the executed expanded query
     * @throws fr.gouv.culture.sdx.exception.SDXException
     */
    Results expandQuery(fr.gouv.culture.sdx.search.lucene.query.Query query, String fieldName, int[] relations, int depth, String[] langs) throws SDXException;

    /**Finds concepts for matching relations at a given depth
     *
     * @param concept   The concept from which relations should be used
     * @param relation  The relation type to search for with a concept
     * @param depth    The depth to which a relation should be evaluated, 0 finds the relation withing the matching concept
     * 1, finds the relation within concept for the matching relation found by the "0 case", etc.
     * @return
     * @throws fr.gouv.culture.sdx.exception.SDXException
     */
    Concept[] getRelations(Concept concept, int relation, int depth) throws SDXException;


    /**Finds concepts for matching relations at a given depth
     *
     * @param concepts   The concepts from which relations should be used
     * @param relations  The relation types to search for with a concept
     * @param depth    The depth to which a relation should be evaluated, 0 finds the relation withing the matching concept
     * 1, finds the relation within concept for the matching relation found by the "0 case", etc.
     * @return
     * @throws fr.gouv.culture.sdx.exception.SDXException
     */
    Concept[] getRelations(Concept[] concepts, int[] relations, int depth) throws SDXException;


    /**Finds concepts for matching relations at a given depth
     *
     * @param concept   The concept from which relations should be used
     * @param relations  The relation types to search for with a concept
     * @param depth    The depth to which a relation should be evaluated, 0 finds the relation withing the matching concept
     * 1, finds the relation within concept for the matching relation found by the "0 case", etc.
     * @return
     * @throws fr.gouv.culture.sdx.exception.SDXException
     */
    Concept[] getRelations(Concept concept, int[] relations, int depth) throws SDXException;

    /**Finds concepts for matching relations at a given depth
     *
     * @param concepts   The concepts from which relations should be used
     * @param relation  The relation type to search for with a concept
     * @param depth    The depth to which a relation should be evaluated, 0 finds the relation withing the matching concept
     * 1, finds the relation within concept for the matching relation found by the "0 case", etc.
     * @return
     * @throws fr.gouv.culture.sdx.exception.SDXException
     */
    Concept[] getRelations(Concept[] concepts, int relation, int depth) throws SDXException;

    /**Finds concepts for matching relations at a given depth
     *
     *@param searchTerm The search term which was used to find the provided concepts
     * @param concepts   The concepts from which relations should be used
     * @param relation  The relation type to search for with a concept
     * @param depth    The depth to which a relation should be evaluated, 0 finds the relation withing the matching concept
     * 1, finds the relation within concept for the matching relation found by the "0 case", etc.
     * @return
     * @throws fr.gouv.culture.sdx.exception.SDXException
     */
    Concept[] getRelations(String searchTerm, Concept[] concepts, int relation, int depth) throws SDXException;

    /**Finds concepts for matching relations at a given depth
     *
     *@param searchTerm The search term which was used to find the provided concepts
     * @param concepts   The concepts from which relations should be used
     * @param relations  The relation types to search for with a concept
     * @param depth    The depth to which a relation should be evaluated, 0 finds the relation withing the matching concept
     * 1, finds the relation within concept for the matching relation found by the "0 case", etc.
     * @return
     * @throws fr.gouv.culture.sdx.exception.SDXException
     */
    Concept[] getRelations(String searchTerm, Concept[] concepts, int[] relations, int depth) throws SDXException;

    /**Finds concepts for matching relations at a given depth
     *
     *@param searchTerm The search term which was used to find the provided concept
     * @param concept   The concept from which relations should be used
     * @param relation  The relation type to search for with a concept
     * @param depth    The depth to which a relation should be evaluated, 0 finds the relation withing the matching concept
     * 1, finds the relation within concept for the matching relation found by the "0 case", etc.
     * @return
     * @throws fr.gouv.culture.sdx.exception.SDXException
     */
    Concept[] getRelations(String searchTerm, Concept concept, int relation, int depth) throws SDXException;

    /**Finds concepts for matching relations at a given depth
     *
     *@param searchTerm The search term which was used to find the provided concepts
     * @param concept   The concepts from which relations should be used
     * @param relations  The relation types to search for with a concept
     * @param depth    The depth to which a relation should be evaluated, 0 finds the relation withing the matching concept
     * 1, finds the relation within concept for the matching relation found by the "0 case", etc.
     * @return
     * @throws fr.gouv.culture.sdx.exception.SDXException
     */
    Concept[] getRelations(String searchTerm, Concept concept, int[] relations, int depth) throws SDXException;

    /* Returns concepts related to a document, filtered by languages.
     *
     * @param   concept     The document.
     * @param   relations   The relations to use.
     * @param   depth       The depth to which relations should be retrieved
     * @param   langs       The list of languages for filtering concepts.
     * @return
     * @throws SDXException
     */
    Concept[] getRelations(Concept concept, int[] relations, int depth, String[] langs) throws SDXException;

    /* Returns concepts related to a document, filtered by languages.
     *
     * @param   concepts     The list of concepts.
     * @param   relations   The relations to use.
     * @param   depth       The depth to which relations should be retrieved
     * @param   langs       The list of languages for filtering concepts.
     * @return
     * @throws SDXException
     */
    Concept[] getRelations(Concept[] concepts, int[] relations, int depth, String[] langs) throws SDXException;

    /* Returns concepts related to a document, filtered by languages.
     *
     * @param   concept     The document.
     * @param   relation   The relation to use.
     * @param   depth       The depth to which relations should be retrieved
     * @param   langs       The list of languages for filtering concepts.
     * @return
     * @throws SDXException
     */
    Concept[] getRelations(Concept concept, int relation, int depth, String[] langs) throws SDXException;

    /* Returns concepts related to a document, filtered by languages.
     *
     * @param   concepts     The list of concepts.
     * @param   relation   The relation to use.
     * @param   depth       The depth to which relations should be retrieved
     * @param   langs       The list of languages for filtering concepts.
     * @return
     * @throws SDXException
     */
    Concept[] getRelations(Concept[] concepts, int relation, int depth, String[] langs) throws SDXException;

    /**Returns related concepts
     *
     * @param concepts The concepts for which relations are desired
     * @return
     */
    Concept[] getRelations(Concept[] concepts) throws SDXException;

    /**Return's related  concepts
     *
     * @param concept The concept for which relations are desired
     * @return
     */
    Concept[] getRelations(Concept concept) throws SDXException;

    /**Return's the default depth for searching relations*/
    int getDefaultDepth();

    /**Return's the default set of relation int's for searching relations*/
    int[] getDefaultRelations();

    /**Filters concepts by a list of languages
     *
     * @param concepts  List of concepts for filtering
     * @param langs     List of langauages (in xml:lang format) which are desired
     * @return
     */
    Concept[] filterByLangs(Concept[] concepts, String[] langs);


}
