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

import java.io.IOException;
import java.io.StringReader;

import org.apache.lucene.analysis.Token;
import org.apache.lucene.analysis.TokenStream;

import fr.gouv.culture.sdx.exception.SDXException;
import fr.gouv.culture.sdx.exception.SDXExceptionCode;
import fr.gouv.culture.sdx.repository.Repository;
import fr.gouv.culture.sdx.search.lucene.analysis.AbstractAnalyzer;
import fr.gouv.culture.sdx.search.lucene.analysis.Analyzer_ar;
//import fr.gouv.culture.sdx.search.lucene.analysis.Analyzer_br;
import fr.gouv.culture.sdx.search.lucene.analysis.Analyzer_cz;
import fr.gouv.culture.sdx.search.lucene.analysis.Analyzer_de;
import fr.gouv.culture.sdx.search.lucene.analysis.Analyzer_en;
import fr.gouv.culture.sdx.search.lucene.analysis.Analyzer_fr;
import fr.gouv.culture.sdx.search.lucene.analysis.DefaultAnalyzer;
import fr.gouv.culture.sdx.utils.Utilities;


/**	Cette classe permet d'utiliser un analyseur de mots de fa&ccedil;on statique,
 * depuis une feuille XSLT par exemple. La {@link String} retourn&eacute;e
 * pr&eacute;sente les diff&eacute;rents {@link Token} accol&eacute;s s&eacute;par&eacute;s
 * par un espace. Par exemple&nbsp;: &quot;<code>l'&eacute;glise de Saint Brice</code>&quot;
 *  donne &quot;<code>eglise saint brice</code>&quot;.
 *
 * @see fr.gouv.culture.sdx.search.lucene.analysis.AbstractAnalyzer
 * @see fr.gouv.culture.sdx.search.lucene.analysis.DefaultAnalyzer
 * @see fr.gouv.culture.sdx.search.lucene.analysis.Analyzer_ar
 * @see fr.gouv.culture.sdx.search.lucene.analysis.Analyzer_br
 * @see fr.gouv.culture.sdx.search.lucene.analysis.Analyzer_cz
 * @see fr.gouv.culture.sdx.search.lucene.analysis.Analyzer_de
 * @see fr.gouv.culture.sdx.search.lucene.analysis.Analyzer_en
 * @see fr.gouv.culture.sdx.search.lucene.analysis.Analyzer_fr
 *
 * @author Malo Pichot
 */
public class AnalyzeString {

	/** Retourne la {@link String} sortie de l'analyseur correspondant. Les mots sont s&eacute;par&eacute;s
	 * ou accol&eacute;s.
	 * @param content	{@link String} La String &agrave; analyser
	 * @param className	{@link String} Le nom de la class repr&eacute;sentant
	 * l'analyseur souhait&eacute; (p.e., {@link Analyzer_fr} pour l'analyseur fran&ccedil;ais)
	 * @param separator	{@link String} Le separateur de mot. Si le param&egrave;tre est <code>null</code>
	 * les mots seront accol&eacute;.
	 * @return	{@link String} Retourne la {@link String} &agrave; sa sortie de
	 * l'analyseur de mots. Si la {@link String} est vide, on la retourne telle quelle.
	 * S'il y a un probl&egrave;me de lecture dans le processus, on retourne "-1".
	 */
	public static String getAnalyzedString(String content, String className, String separator)
		throws SDXException {


		if( !content.trim().equals("") ){
			String	result	= content,
					sep		= (separator==null) ? "" : separator;
			StringReader str = new StringReader(content);
			Token tmpToken;
			StringBuffer strb = new StringBuffer(content.length());
			AbstractAnalyzer _analyzer = null;

			//On choisit l'analyseur de mots suivant le nom de classe recu
			if ( className==null || className.equals("") ) {
				_analyzer = new Analyzer_fr();
			}
			else if( className.equals("Analyzer_ar") ){
				_analyzer = new Analyzer_ar();
			}
			else if( className.equals("Analyzer_br") ){
				//_analyzer = new Analyzer_br();
				System.err.println("L'analyseur Bresilien ne fonctionne pas :-(");
				_analyzer = new DefaultAnalyzer();
			}
			else if( className.equals("Analyzer_cz") ){
				_analyzer = new Analyzer_cz();
			}
			else if( className.equals("Analyzer_de") ){
				_analyzer = new Analyzer_de();
			}
			else if( className.equals("Analyzer_en") ){
				_analyzer = new Analyzer_en();
			}
			else if( className.equals("Analyzer_fr") ){
				_analyzer = new Analyzer_fr();
			}
			else if( className.equals("Analyzer_ru") ){
				_analyzer = new Analyzer_ar();
			}
			else{
				try {
					Object l_obj = Utilities.getObjectForClassName(null, className, null, className, null);
			        Class l_objClass = l_obj.getClass();
			        if ( !(l_obj instanceof Analyzer) || !(l_obj instanceof org.apache.lucene.analysis.Analyzer) ) {
			            //the object doesn't implement our interface
			            String[] args = new String[3];
			            args[0] = Repository.CLASS_NAME_SUFFIX;
			            if (l_objClass != null) { args[1] = l_objClass.getName(); }
			            args[2] = className;
			            throw new SDXException(null, SDXExceptionCode.ERROR_CLASS_NOT_INSTANCEOF_SDX_INTERFACE, args, null);
			        }
			        else{
			        	_analyzer = (AbstractAnalyzer) l_obj;
			        }
				} catch (Exception e){
					throw new SDXException("Impossible to use "+className+" as an analyzer.",e);
				}
			}

			if(_analyzer==null) _analyzer = new Analyzer_fr();
			
			//On envoie le tout dans l'analyseur de mots.
			TokenStream tmpTokenStream = _analyzer.tokenStream("dummy", str);

			//Maintenant, on va recuperer la sortie et en faire une String
			try {

				int nb = 0;
				while( (tmpToken = tmpTokenStream.next())!=null ){
					nb++;
					if( !tmpToken.termText().trim().equals("") ) {
						if (nb!=1) strb.append(sep);
						strb.append(tmpToken.termText());
					}
				}

				result = strb.toString();

			} catch (IOException e) {//Probleme de lecture, on renvoie "-1"
				System.err.println(e);
				result = "-1";
			}

			//C'est fini !
			return result;
		}
		//content est vide
		else return "";
	}

	/** Retourne la {@link String} &agrave; sa sortie de l'analyseur de mots par
	 * d&eacute;faut : {@link Analyzer_fr}. Les mots sont accol&eacute;s.
	 * @param content La string &agrave; analyser.
	 * @return {@link String} Si la {@link String} n'est pas vide retourne la {@link String}
	 * &agrave; sa sortie de l'analyseur de mots fran&ccedil;ais. Les mots sont accol&eacute;s,
	 * sans s&eacute;parateur.
	 */
	public static String getAnalyzedString(String content){

		try {
			if(!content.trim().equals(""))
				return getAnalyzedString(content, "Analyzer_fr", null);
			else return "";
		} catch (SDXException sdxe){
			return "-1";
		}


	}

	/** Retourne la {@link String} &agrave; sa sortie de l'analyseur de mots souhait&eacute;. Les mots
	 * sont accol&eacute;s
	 * @param content La {@link String} &agrave; analyser.
	 * @param className	Le nom de la classe Java repr&eacute;sentant l'analyseur &agrave; employer.
	 * @return {@link String} Retourne la {@link String} analys&eacute; par l'analyseur souhait&eacute;.
	 * Les mots sont accol&eacute;s, sans s&eacute;parateur.
	 */
	public static String getAnalyzedString(String content, String className){
		try {
			if(!content.trim().equals(""))
				return getAnalyzedString(content, className, null);
			else return "";
		} catch (SDXException sdxe){
			return "-1";
		}
	}
}