/***********************************************************************************************************************
 * Copyright (c) 2008 empolis GmbH and brox IT Solutions GmbH. All rights reserved. This program and the accompanying
 * materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors: August Georg Schmidt (brox IT Solutions GmbH) - initial API and implementation
 **********************************************************************************************************************/

package org.eclipse.smila.search;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Enumeration;
import java.util.Formatter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.smila.search.exceptions.AFException;
import org.eclipse.smila.search.index.IndexConnection;
import org.eclipse.smila.search.index.IndexException;
import org.eclipse.smila.search.index.IndexManager;
import org.eclipse.smila.search.plugin.Plugin;
import org.eclipse.smila.search.plugin.PluginFactory;
import org.eclipse.smila.search.search.tools.advsearch.AdvSearchException;
import org.eclipse.smila.search.search.tools.advsearch.IAdvSearch;
import org.eclipse.smila.search.search.tools.advsearch.IQueryExpression;
import org.eclipse.smila.search.search.tools.search.DAnyFinderSearch;
import org.eclipse.smila.search.search.tools.search.DAnyFinderSearchCodec;
import org.eclipse.smila.search.search.tools.search.DQuery;
import org.eclipse.smila.search.search.tools.search.DSearchException;
import org.eclipse.smila.search.search.tools.searchresult.DAnyFinderSearchResult;
import org.eclipse.smila.search.search.tools.searchresult.DAnyFinderSearchResultCodec;
import org.eclipse.smila.search.search.tools.searchresult.DHit;
import org.eclipse.smila.search.search.tools.searchresult.DHitDistribution;
import org.eclipse.smila.search.search.tools.searchresult.DItem;
import org.eclipse.smila.search.search.tools.searchresult.DResult;
import org.eclipse.smila.search.search.tools.searchresult.DSearchResultException;
import org.eclipse.smila.search.tools.errormessage.DErrorMessage;
import org.eclipse.smila.tools.XMLUtils;
import org.eclipse.smila.tools.XMLUtilsConfig;
import org.eclipse.smila.tools.XMLUtilsException;
import org.eclipse.smila.tools.cache.CacheException;
import org.eclipse.smila.tools.cache.CacheManager;
import org.eclipse.smila.tools.cache.CacheManagerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * Search Class.
 * 
 * @author August Georg Schmidt (BROX)
 * @version 1.0
 */
public abstract class AFSearch {

  static {
    EIFActivator.registerSchemas();
  }

  /**
   * Hidden constructor. Class must be used via static methods.
   */
  private AFSearch() {
  }

  /**
   * takes the given bytearray which must rsult to a valid AnyFinderSearch- or AnyFinderAdvancedSearch-XML and performs
   * a search for it.
   * 
   * @param anyFinderAnySearchStream
   *          Search query as byte[].
   * @return Search result.
   * @throws AFException
   *           Exception during search.
   */
  public static DAnyFinderSearchResult search(byte[] anyFinderAnySearchStream) throws AFException {
    final Log log = LogFactory.getLog(AFSearch.class);
    DAnyFinderSearchResult dSR = null;
    try {
      // get anyfinder search
      final Document doc = XMLUtils.parse(anyFinderAnySearchStream, new XMLUtilsConfig());
      final Element root = doc.getDocumentElement();
      if ("AnyFinderSearch".equals(root.getLocalName())) {
        dSR = AFSearch.search(DAnyFinderSearchCodec.decode(root));
      } else if ("AnyFinderAdvancedSearch".equals(root.getLocalName())) {
        final Plugin plugin = PluginFactory.getPlugin();
        dSR = AFSearch.search(plugin.getAdvSearchAccess().decode(root));
      } else {
        dSR = new DAnyFinderSearchResult();

        final DErrorMessage dErrorMessage = new DErrorMessage();
        dErrorMessage.setCode("AF-ERR");
        dErrorMessage.setMessage("AnyFinder Error");
        dErrorMessage.setDetail("Given ByteArray is neither a AnyFinderSearch nor an AnyFinderAdvancedSearch");
        dErrorMessage.setSource(AFSearch.class.getName());
        dSR.setErrorMessage(dErrorMessage);
        log.error(dErrorMessage.getDetail());
      }
    } catch (final XMLUtilsException e) {
      log.error(e.getMessage());
      throw new AFException("Unable to parse given xml stream", e);
    } catch (final AdvSearchException e) {
      throw new AFException("Unable to decode AdvancedSearch", e);
    } catch (final DSearchException e) {
      throw new AFException("Unable to decode search: " + e.getMessage());
    } catch (final ClassCastException e) {
      throw new AFException("Error during class conversion", e);
    }

    // exceute search
    return dSR;
  }

  /**
   * Execute search for a <code>DAnyFinderSearch</code> object.
   * 
   * @param dSimpleSearch
   *          Search to execute.
   * @return Search result.
   */
  public static DAnyFinderSearchResult search(DAnyFinderSearch dSimpleSearch) {
    final Log log = LogFactory.getLog(AFSearch.class);

    final DAnyFinderSearchResult dAnyFinderSearchResult = new DAnyFinderSearchResult();
    final Enumeration queries = dSimpleSearch.getQueries();
    if (queries != null) {
      while (queries.hasMoreElements()) {
        DQuery dQuery = null;
        long start = 0;
        try {
          dQuery = (DQuery) queries.nextElement();
          String indexName = dQuery.getIndexName();

          if (indexName != null) {
            indexName = indexName.trim();
          } else {
            throw new IndexException("index name is not specified in query");
          }

          if ("".equals(indexName)) {
            throw new IndexException("index name is empty in query");
          }

          final CacheManager<String, DResult> cache = CacheManagerFactory.getInstance();

          start = System.currentTimeMillis();
          if (indexName.indexOf(';') == -1) {

            final String sQuery = dQuery.toString();
            final String queryHash = getMD5Hash(sQuery);
            final String queryName = byteArrayToString(sQuery.getBytes());
            final String qualifiedNameInCache = "/" + dQuery.getIndexName() + "/" + queryHash;
            DResult dResult = null;
            if (cache.exists(qualifiedNameInCache, queryName)) {
              dResult = cache.get(qualifiedNameInCache, queryName);
              if (dResult != null) {
                dAnyFinderSearchResult.addResult(dResult);
              }
            } else {
              // get Pool, do query, and release it
              boolean killPoolConnection = false;
              IndexConnection indexConnection = null;
              try {
                indexConnection = IndexManager.getInstance(indexName);
                if (log.isInfoEnabled()) {
                  log.info("Time to get instance: " + (System.currentTimeMillis() - start) + "[ms]");
                }
                // TODO:
                dResult = null; //indexConnection.doQuery(dQuery);
                if (dResult != null) {
                  dAnyFinderSearchResult.addResult(dResult);
                }
                if ((dResult != null) && (dResult.getErrorMessage() == null)) {
                  cache.put(qualifiedNameInCache, queryName, dResult);
                }
              } catch (final IndexException e) {
                killPoolConnection = true;
                throw e;
              } finally {
                if (indexConnection != null) {
                  IndexManager.releaseInstance(indexConnection, killPoolConnection);
                  if (log.isDebugEnabled()) {
                    log.debug("Time to Release: " + (System.currentTimeMillis() - start) + "[ms]");
                  }
                }
              }
            }
          } else {
            searchOnMultipleIndizes(indexName, dQuery, dAnyFinderSearchResult, start);
          }
          if (log.isInfoEnabled()) {
            log.info("Time to Query result: " + (System.currentTimeMillis() - start) + "[ms]");
          }
        } catch (final IndexException e) {
          createErrorMessage(dAnyFinderSearchResult, dQuery.getIndexName(), e);
        } catch (final Exception e) {
          createErrorMessage(dAnyFinderSearchResult, dQuery.getIndexName(), e);
        } // try
      } // while
    } // if

    return dAnyFinderSearchResult;
  }

  /**
   * Create a MD5 Hash from a String.
   * 
   * @param in
   *          String to create MD5 hash from.
   * @return MD5 Hash as String.
   */
  private static String getMD5Hash(String in) {
    final Log log = LogFactory.getLog(AFSearch.class);
    final StringBuffer result = new StringBuffer(32);
    try {
      final MessageDigest md5 = MessageDigest.getInstance("MD5");
      md5.update(in.getBytes());
      final Formatter f = new Formatter(result);
      for (final byte b : md5.digest()) {
        f.format("%02x", b);
      }
    } catch (final NoSuchAlgorithmException ex) {
      if (log.isErrorEnabled()) {
        log.error(ex);
      }
    }
    return result.toString();
  }

  /**
   * Create a String from a byte[].
   * 
   * @param bytes
   *          Byte[] for string conversion.
   * @return Byte[] as String.
   */
  private static String byteArrayToString(byte[] bytes) {
    final StringBuffer result = new StringBuffer(32);
    final Formatter f = new Formatter(result);
    for (final byte b : bytes) {
      f.format("%02x", b);
    }
    return result.toString();
  }

  /**
   * Search on multiple indices with extended search result merging and caching.
   * 
   * @param indexName
   *          Index names for search query. (';' is delemiter)
   * @param dQuery
   *          Search query to execute.
   * @param dAnyFinderSearchResult
   *          Search result.
   * @param startTime
   *          Start time for logging.
   * @throws IndexException
   *           Search problems.
   * @throws CacheException
   *           Exception during cache access.
   */
  private static void searchOnMultipleIndizes(String indexName, DQuery dQuery,
    final DAnyFinderSearchResult dAnyFinderSearchResult, long startTime) throws IndexException, CacheException {
    final Log log = LogFactory.getLog(AFSearch.class);
    String[] indexNames = indexName.split(";");
    indexNames = normalizeIndexNames(indexNames);

    final HashMap<String, DHitDistribution> hitDistributions = getHitDistributionsForQuery(indexNames, dQuery);

    int startHits = 0;
    if (dQuery.getStartHits() != null) {
      startHits = dQuery.getStartHits().intValue();
    }
    final QueryScope[] queryScopes =
      FederatedQueryHandling.calculateQueries(indexNames, startHits, dQuery.getMaxHits(), hitDistributions);

    final CacheManager<String, DResult> cache = CacheManagerFactory.getInstance();
    final DResult dMergedResult = new DResult();
    dMergedResult.setName(indexName);
    for (final QueryScope queryScope : queryScopes) {

      boolean killPoolConnection = false;
      IndexConnection indexConnection = null;
      try {
        final long start2 = System.currentTimeMillis();
        dQuery.setIndexName(queryScope.getIndexName());
        dQuery.setStartHits(queryScope.getStart());
        dQuery.setMaxHits(queryScope.getHits());

        final String sQuery = dQuery.toString();
        final String queryHash = getMD5Hash(sQuery);
        final String queryName = byteArrayToString(sQuery.getBytes());
        final String qualifiedNameInCache = "/" + dQuery.getIndexName() + "/" + queryHash;
        DResult dResult = null;
        if (cache.exists(qualifiedNameInCache, queryName)) {
          dResult = cache.get(qualifiedNameInCache, queryName);
        } else {
          indexConnection = IndexManager.getInstance(queryScope.getIndexName());
          if (log.isInfoEnabled()) {
            log.info("Time to get instance [" + queryScope.getIndexName() + "]: "
              + (System.currentTimeMillis() - start2) + "[ms]");
          }
          // TODO:
          dResult = null; //indexConnection.doQuery(dQuery);

          if ((dResult != null) && (dResult.getErrorMessage() == null)) {
            cache.put(qualifiedNameInCache, queryName, dResult);
          }
        }

        if (dResult != null) {

          if (dResult.getErrorMessage() != null) {
            dMergedResult.clearItems();
            dMergedResult.setErrorMessage(dResult.getErrorMessage());
            dMergedResult.setHitDistribution(null);
            break;
          }

          addItemsToExistingResult(startHits, dMergedResult, dResult, queryScope);
        }
      } catch (final IndexException e) {
        killPoolConnection = true;
        throw e;
      } finally {
        if (indexConnection != null) {
          IndexManager.releaseInstance(indexConnection, killPoolConnection);
          if (log.isDebugEnabled()) {
            log.debug("Time to Release [" + queryScope.getIndexName() + "]: "
              + (System.currentTimeMillis() - startTime) + "[ms]");
          }
        }
      }

    }

    final HashMap<Integer, DHit> hits = new HashMap<Integer, DHit>();
    for (final DHitDistribution hitDistribution : hitDistributions.values()) {
      updateHitDistribution(hitDistribution, hits);
    }

    final DHitDistribution hd = new DHitDistribution();
    for (final Iterator iter = hits.values().iterator(); iter.hasNext();) {
      final DHit hit = (DHit) iter.next();
      hd.addHit(hit);
    }
    if (hd.getHitsCount() != 0) {
      dMergedResult.setHitDistribution(hd);
    }
    dMergedResult.setHits(dMergedResult.getItemsCount());
    dAnyFinderSearchResult.addResult(dMergedResult);
  }

  /**
   * This function removes dublicate entries from a set of index names. Index names are treated case sensitive.
   * 
   * @param indexNames
   *          Index names to normalize.
   * @return Normalized index names.
   */
  public static String[] normalizeIndexNames(String[] indexNames) {
    final Set<String> indexNamesAsSet = new HashSet<String>();

    // TODO: check order of returned index names. ==> order could probably have a result for paging

    for (final String indexName : indexNames) {
      indexNamesAsSet.add(indexName.trim());
    }

    return indexNamesAsSet.toArray(new String[0]);
  }

  /**
   * @param indexNames
   *          Array of indices to query on.
   * @param query
   *          Base query for request.
   * @return DHitDistribution per index.
   * @throws IndexException
   *           Exception statitng that a search has failed.
   * @throws CacheException
   *           Exception during cache access.
   */
  private static HashMap<String, DHitDistribution> getHitDistributionsForQuery(String[] indexNames, DQuery query)
    throws IndexException, CacheException {
    final DQuery queryClone = (DQuery) query.clone();

    // start at first document; these is a good chance for a cached result
    queryClone.setStartHits(0);

    final HashMap<String, DHitDistribution> hitDistributions = new HashMap<String, DHitDistribution>();
    final CacheManager<String, DResult> cache = CacheManagerFactory.getInstance();

    for (final String indexName : indexNames) {
      queryClone.setIndexName(indexName);
      final String sQuery = queryClone.toString();
      final String queryHash = getMD5Hash(sQuery);
      final String queryName = byteArrayToString(sQuery.getBytes());
      boolean killPoolConnection = false;
      IndexConnection indexConnection = null;
      try {
        DResult dResult = null;
        final String qualifiedNameInCache = "/" + queryClone.getIndexName() + "/" + queryHash;
        if (cache.exists(qualifiedNameInCache, queryName)) {
          dResult = cache.get(qualifiedNameInCache, queryName);
          dResult = cache.get(qualifiedNameInCache, queryName);
          dResult = cache.get(qualifiedNameInCache, queryName);
          dResult = cache.get(qualifiedNameInCache, queryName);
          dResult = cache.get(qualifiedNameInCache, queryName);
        } else {
          indexConnection = IndexManager.getInstance(indexName);
          // TODO:
          dResult = null; //indexConnection.doQuery(queryClone);
          cache.put(qualifiedNameInCache, queryName, dResult);
        }

        if ((dResult != null) && (dResult.getErrorMessage() == null)) {
          hitDistributions.put(indexName, dResult.getHitDistribution());
        }
      } catch (final IndexException e) {
        killPoolConnection = true;
        throw e;
      } finally {
        if (indexConnection != null) {
          IndexManager.releaseInstance(indexConnection, killPoolConnection);
        }
      }
    }

    return hitDistributions;
  }

  /**
   * Add items to an existing search result. The basis structure for the hit distribution is also updated.
   * 
   * @param startHits
   *          Start of hits in result set.
   * @param targetResult
   *          Target search result.
   * @param sourceResult
   *          Source search result.
   * @param queryScope
   *          Query scope item selection.
   */
  private static void addItemsToExistingResult(final int startHits, final DResult targetResult,
    final DResult sourceResult, final QueryScope queryScope) {
    // add items
    int recordsSelected = 0;
    final int resultPositionStartSelection = (queryScope.getStartSelection() % queryScope.getHits()) - 1;
    for (int j = 0; j < sourceResult.getItemsCount(); j++) {
      if ((j >= resultPositionStartSelection) && (recordsSelected < queryScope.getRecordsToSelect())) {
        recordsSelected++;
        final DItem item = (DItem) sourceResult.getItem(j).clone();
        item.setPos(targetResult.getItemsCount() + startHits);
        targetResult.addItem(item);
      }
    }
  }

  /**
   * Update hit distribution.
   * 
   * @param srcHD
   *          Source hit distribution.
   * @param hits
   *          Structure containing the merged hit distribution.
   */
  private static void updateHitDistribution(final DHitDistribution srcHD, final HashMap<Integer, DHit> hits) {
    for (int j = 0; j < srcHD.getHitsCount(); j++) {
      final DHit srcHit = srcHD.getHit(j);

      if (hits.containsKey(new Integer(srcHit.getScore()))) {
        final DHit hit = hits.get(new Integer(srcHit.getScore()));
        hit.setHits(srcHit.getHits() + hit.getHits());
      } else {
        hits.put(new Integer(srcHit.getScore()), new DHit(srcHit.getScore(), srcHit.getHits()));
      }
    }
  }

  /**
   * Takes <code>IAdvSearch</code> object and performs a search with it. The result could be multiple queries.
   * 
   * @param dAdvancedSearch
   *          Search to be executed.
   * @return Search result.
   */
  public static DAnyFinderSearchResult search(IAdvSearch dAdvancedSearch) {

    final DAnyFinderSearchResult dAnyFinderSearchResult = new DAnyFinderSearchResult();

    // technically several QE are supported per AFAS but only one is currently allowed
    final Iterator queries = dAdvancedSearch.getQueryExpressions();
    while (queries.hasNext()) {
      final IQueryExpression dQE = (IQueryExpression) queries.next();
      final DResult dResult = search(dQE, dQE.getIndexName());
      if (dResult != null) {
        dAnyFinderSearchResult.addResult(dResult);
      }
    } // while

    return dAnyFinderSearchResult;
  }

  /**
   * Takes either a <code>.search.DQuery</code> or a <code>.advsearch.DQueryExpression</code> object and performs
   * with that a search.
   * 
   * @param dAnyQuery
   *          DQuery or IQueryExpression object containing an query to execute.
   * @param indexName
   *          Name of index onto which the query is executed.
   * @return Search result.
   */
  private static DResult search(Object dAnyQuery, String indexName) {
    final Log log = LogFactory.getLog(AFSearch.class);
    DResult dResult = null;
    IndexConnection indexConnection = null;
    long start = 0;
    boolean killPoolConnection = false;

    // get Pool, do query, and release it
    try {
      start = System.currentTimeMillis();

      indexConnection = IndexManager.getInstance(indexName);
      if (log.isInfoEnabled()) {
        log.info("Time to get instance: " + (System.currentTimeMillis() - start) + "[ms]");
      }

      // perform query
      if (dAnyQuery instanceof DQuery) {
        // TODO:
        dResult = null; //indexConnection.doQuery((DQuery) dAnyQuery);
      } else if (dAnyQuery instanceof IQueryExpression) {
        // TODO:
        dResult = null; //indexConnection.doQuery((IQueryExpression) dAnyQuery);
      } else {
        dResult = new DResult();
        dResult.setName(indexName);
        dResult.setHits(0);
        final DErrorMessage dErrorMessage = new DErrorMessage();
        dErrorMessage.setCode("AF-ERR");
        dErrorMessage.setMessage("AnyFinder Error");
        dErrorMessage.setDetail("Object dAnyQuery is neither of Class DQuery nor DQueryExpression");
        dErrorMessage.setSource(AFSearch.class.getName());
        dResult.setErrorMessage(dErrorMessage);
        log.error(dErrorMessage.getDetail());
        killPoolConnection = true;
      }

      if (log.isInfoEnabled()) {
        log.info("Time to Query result: " + (System.currentTimeMillis() - start) + "[ms]");
      }
    } catch (final IndexException e) {
      dResult = createErrorMessage2(indexName, e);
      killPoolConnection = true;
    } catch (final Exception e) {
      dResult = createErrorMessage2(indexName, e);
      killPoolConnection = true;
    } finally {
      if (indexConnection != null) {
        IndexManager.releaseInstance(indexConnection, killPoolConnection);
        if (log.isDebugEnabled()) {
          log.debug("Time to Release: " + (System.currentTimeMillis() - start) + "[ms]");
        }
      }
    } // try
    return dResult;
  }

  /**
   * Prepare and log error message for result.
   * 
   * @param dAnyFinderSearchResult
   *          Search result where the error is appended.
   * @param indexName
   *          Index name.
   * @param exception
   *          Exception occured in code.
   */
  private static void createErrorMessage(final DAnyFinderSearchResult dAnyFinderSearchResult, String indexName,
    Exception exception) {
    final Log log = LogFactory.getLog(AFSearch.class);
    final DResult dResult = prepareErrorMessageFromException(indexName, exception);
    dAnyFinderSearchResult.addResult(dResult);
    log.error("", exception);
  }

  /**
   * Prepare DResult containing error description.
   * 
   * @param indexName
   *          Index name.
   * @param exception
   *          Exception occured in code.
   * @return DResult containing error description.
   */
  private static DResult prepareErrorMessageFromException(String indexName, Exception exception) {
    final DResult dResult = new DResult();
    dResult.setName(indexName);
    dResult.setHits(0);
    final DErrorMessage dErrorMessage = new DErrorMessage();
    dErrorMessage.setCode("AF-ERR");
    dErrorMessage.setMessage("AnyFinder Error");
    if (exception.getMessage() != null) {
      dErrorMessage.setDetail(exception.getMessage());
    } else {
      dErrorMessage.setDetail(exception.getClass().getName());
    }
    dErrorMessage.setSource(AFSearch.class.getName());
    dResult.setErrorMessage(dErrorMessage);
    return dResult;
  }

  /**
   * Create error message result structure.
   * 
   * @param indexName
   *          Index name where the error occured in request.
   * @param exception
   *          Exception in code.
   * @return DResult containing an error message.
   */
  private static DResult createErrorMessage2(String indexName, Exception exception) {
    final Log log = LogFactory.getLog(AFSearch.class);
    final DResult dResult = prepareErrorMessageFromException(indexName, exception);
    log.error("", exception);
    return dResult;
  }

  /**
   * Converts a <code>DAnyFinderSearchResult</code> to a byte[].
   * 
   * @param dAnyFinderSearchResult
   *          search result to transform.
   * @return Streamed search result.
   * @throws AFException
   *           Streaming error.
   */
  public static final byte[] toStream(DAnyFinderSearchResult dAnyFinderSearchResult) throws AFException {
    try {
      final Document doc = DAnyFinderSearchResultCodec.encode(dAnyFinderSearchResult);
      final byte[] bytes = XMLUtils.stream(doc.getDocumentElement(), true, true);
      return bytes;
    } catch (final DSearchResultException e) {
      throw new AFException("unable encode AnyFinderSearchResult", e);
    } catch (final XMLUtilsException e) {
      throw new AFException("unable to stream AnyFinderSearchResult", e);
    }
  }

}
