/***********************************************************************************************************************
 * Copyright (c) 2009 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: Juergen Schumacher (empolis GmbH) - initial API and implementation
 **********************************************************************************************************************/

package org.eclipse.smila.search.servlet;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Collection;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.smila.search.api.SearchService;
import org.eclipse.smila.search.api.helper.QueryBuilder;
import org.eclipse.smila.search.api.internal.ResultDocumentBuilder;
import org.eclipse.smila.search.servlet.activator.Activator;
import org.eclipse.smila.search.servlet.solr.IndexNamesHelper;
import org.eclipse.smila.utils.config.ConfigUtils;
import org.eclipse.smila.utils.xml.XMLUtils;
import org.eclipse.smila.utils.xml.XMLUtilsException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * @author jschumacher
 *
 */
public class SMILASearchServlet extends HttpServlet {

  /**
   * default scriptAndFunction name.
   */
  public static final String DEFAULT_SCRIPTANDFUNCTION = "search.process";

  /**
   * default pipeline name.
   */
  public static final String DEFAULT_PIPELINE = "SearchPipeline";

  /**
   * name of parameter specifying the pipeline name.
   */
  public static final String PARAM_PIPELINE = "pipeline";

  /**
   * name of parameter specifying the workflow name.
   */
  public static final String PARAM_SCRIPTANDFUNCTION = "script";

  /**
   * default stylesheet name.
   */
  public static final String DEFAULT_STYLESHEET = "SMILASearchDefault";

  /**
   * Element name for the index names list.
   */
  public static final String ELEMENT_INDEX_NAMES = "IndexNames";

  /**
   * Element name for a index names list entry.
   */
  public static final String ELEMENT_INDEX_NAME = "IndexName";

  /**
   * because it's serializable.
   */
  private static final long serialVersionUID = 1L;

  /**
   * Logging.
   */
  private final Log _log = LogFactory.getLog(getClass());

  /**
   * helper for parsing multipart requests, used to include binary attachments.
   */
  private ServletFileUpload _fileUpload;

  /**
   * helper for converting errors to XML.
   */
  private ResultDocumentBuilder _errorBuilder;

  /**
   * {@inheritDoc}
   *
   * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest,
   *      javax.servlet.http.HttpServletResponse)
   */
  @Override
  protected void doGet(final HttpServletRequest request, final HttpServletResponse response)
    throws ServletException, IOException {

    processRequest(request, response);
  }

  /**
   * {@inheritDoc}
   *
   * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest,
   *      javax.servlet.http.HttpServletResponse)
   */
  @Override
  protected void doPost(final HttpServletRequest request, final HttpServletResponse response)
    throws ServletException, IOException {

    processRequest(request, response);
  }

  /**
   * {@inheritDoc}
   *
   * @see javax.servlet.http.HttpServlet#doPut(javax.servlet.http.HttpServletRequest,
   *      javax.servlet.http.HttpServletResponse)
   */
  @Override
  protected void doPut(final HttpServletRequest request, final HttpServletResponse response)
    throws ServletException, IOException {

    processRequest(request, response);
  }

  private String getDefaultValue(final String value, final String defaultValue) {
    String result = defaultValue;
    if ((value != null) && (value.length() > 0)) {
      result = value;
    }
    return result;
  }

  /**
   * Arguments "pipeline" and "script". if both are there, "script" wins. This one is for non-multipart requests
   */
  private boolean isScriptingRequestSingle(final HttpServletRequest request, StringBuilder pipelineOrScriptName) {
    boolean result = true;
    pipelineOrScriptName.append(DEFAULT_SCRIPTANDFUNCTION);

    final String pipeVal = request.getParameter(PARAM_PIPELINE);
    if (pipeVal != null) {
      pipelineOrScriptName.setLength(0);
      pipelineOrScriptName.append(getDefaultValue(pipeVal, DEFAULT_PIPELINE));
      result = false;
    }

    final String scriptVal = request.getParameter(PARAM_SCRIPTANDFUNCTION);
    if (request.getParameter(PARAM_SCRIPTANDFUNCTION) != null) {
      pipelineOrScriptName.setLength(0);
      pipelineOrScriptName.append(getDefaultValue(scriptVal, DEFAULT_SCRIPTANDFUNCTION));
      result = true;
    }
    return result;
  }

  /**
   * Arguments "pipeline" and "script". if both are there, "script" wins. This one is for multipart requests
   */
  private boolean isScriptingRequestMultiPart(final MultiPartRequestParser parser,
    StringBuilder pipelineOrScriptName) {
    boolean result = true;
    pipelineOrScriptName.append(DEFAULT_SCRIPTANDFUNCTION);

    final String pipeVal = parser.getSingleParameterValue(PARAM_PIPELINE);
    if (pipeVal != null) {
      pipelineOrScriptName.setLength(0);
      pipelineOrScriptName.append(getDefaultValue(pipeVal, DEFAULT_PIPELINE));
      result = false;
    }
    final String scriptVal = parser.getSingleParameterValue(PARAM_SCRIPTANDFUNCTION);
    if (scriptVal != null) {
      pipelineOrScriptName.setLength(0);
      pipelineOrScriptName.append(getDefaultValue(scriptVal, DEFAULT_SCRIPTANDFUNCTION));
      result = true;
    }
    return result;
  }

  private void postProcessResult(final HttpServletResponse response, String stylesheet, final String showXml,
    final Document resultDoc) throws ServletException, IOException {
    if (StringUtils.isEmpty(stylesheet)) {
      // TODO: get default stylesheet name from configuration
      stylesheet = DEFAULT_STYLESHEET;
    }
    try {
      byte[] result = null;
      if ((showXml != null) && Boolean.valueOf(showXml)) {
        response.setContentType("text/xml");
        result = XMLUtils.stream(resultDoc.getDocumentElement(), false);
      } else {
        response.setContentType("text/html;charset=UTF-8");
        result = transform(resultDoc, stylesheet);
      }
      response.getOutputStream().write(result);
      response.getOutputStream().flush();
    } catch (final XMLUtilsException e) {
      if (_log.isErrorEnabled()) {
        _log.error("", e);
      }
    }
  }

  /**
   * extract query parameters from request, create SMILA Query record and send it to a SearchService, transform the DOM.
   * Result to HTML using an XSLT stylesheet.
   *
   * @param request
   *          HTTP request
   * @param response
   *          HTTP response
   * @throws ServletException
   *           error during processing
   * @throws IOException
   *           error writing result to response stream
   */
  protected void processRequest(final HttpServletRequest request, final HttpServletResponse response)
    throws ServletException, IOException {
    try {
      request.setCharacterEncoding("UTF-8");
    } catch (final UnsupportedEncodingException e) {
      throw new ServletException("unable to set request encoding to UTF-8");
    }
    final boolean isMultipart = ServletFileUpload.isMultipartContent(request);

    boolean scriptingCall = true;
    String pipelineOrScriptName = "";

    QueryBuilder query = null;
    if (isMultipart) {
      try {
        final List<FileItem> items = getFileUploadParser().parseRequest(request);
        final MultiPartRequestParser parser = new MultiPartRequestParser();
        parser.initialParse(items);
        final StringBuilder sb = new StringBuilder();
        scriptingCall = isScriptingRequestMultiPart(parser, sb);
        pipelineOrScriptName = sb.toString();
        query = parser.parse();
      } catch (final FileUploadException ex) {
        throw new ServletException("error parsing multipart request", ex);
      }

    } else {
      final HttpRequestParser parser = new HttpRequestParser();
      final StringBuilder sb = new StringBuilder();
      scriptingCall = isScriptingRequestSingle(request, sb);
      pipelineOrScriptName = sb.toString();
      query = parser.parse(request);
    }
    final SearchService searchService = Activator.getInstance().getSearchService();
    Document resultDoc = null;
    try {
      if (searchService == null) {
        resultDoc =
          getErrorBuilder().buildError(
            new ServletException("The SearchService is not available. Please wait a moment and try again."));
      } else {
        if (scriptingCall) {
          resultDoc = searchService.searchAsXmlWithScript(pipelineOrScriptName, query.getQuery());
        } else {
          resultDoc = searchService.searchAsXml(pipelineOrScriptName, query.getQuery());
        }
        appendIndexList(resultDoc);
      }
    } catch (final ParserConfigurationException ex) {
      throw new ServletException(
        "Error creating an XML result to display. Something is completely wrong in the SMILA setup.", ex);
    }
    postProcessResult(response, query.getMetadata().getStringValue("style"),
      query.getMetadata().getStringValue("showXml"), resultDoc);
  }

  /**
   * transform DOM documment using stylesheet.
   *
   * @param doc
   *          DOM search result document
   * @param stylesheet
   *          stylesheet name (without .xsl suffix)
   * @return HTML result
   * @throws ServletException
   *           error during transformation
   */
  protected byte[] transform(final Document doc, final String stylesheet) throws ServletException {
    final DOMSource xmlDomSource = new DOMSource(doc);

    // sw recieves the transformation's result.
    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
    final StreamResult stream = new StreamResult(baos);

    // transform via StreamResult into the StringWriter
    InputStream is = null;
    try {
      is = ConfigUtils.getConfigStream(Activator.BUNDLE_NAME, stylesheet + ".xsl");
      final Document xslDoc = XMLUtils.parse(is, false);
      final Transformer transformer = getXSLTransformer(xslDoc);
      transformer.setParameter("stylesheet", stylesheet);
      transformer.transform(xmlDomSource, stream);
    } catch (final XMLUtilsException xue) {
      throw new ServletException("the stylesheet is not valid [" + stylesheet + ".xsl]", xue);
    } catch (final TransformerException te) {
      throw new ServletException("Error ocured while transforming!", te);
    } finally {
      IOUtils.closeQuietly(is);
    }

    return baos.toByteArray();
  }

  /**
   * create XSL transformer for stylesheet.
   *
   * @param xslDoc
   *          XSL DOM document
   * @return XSL transformer
   * @throws ServletException
   *           error.
   */
  protected Transformer getXSLTransformer(final Document xslDoc) throws ServletException {
    final TransformerFactory tFactory = TransformerFactory.newInstance();
    if (tFactory.getFeature(DOMSource.FEATURE) && tFactory.getFeature(StreamResult.FEATURE)) {

      final DOMSource xslDomSource = new DOMSource(xslDoc);

      try {
        return tFactory.newTransformer(xslDomSource);
      } catch (final TransformerConfigurationException e) {
        throw new ServletException("error while creating the transformer", e);
      }
    } else {
      throw new ServletException("the transformer [" + tFactory.getClass().getName()
        + "] doesn't support the used DOMSource or StreamResult");
    }
  }

  /**
   * Appends a list of index names to the document.
   *
   * @param doc
   *          the document to append the list to
   */
  protected void appendIndexList(final Document doc) {
    Collection<String> indexNames = null;
    try {
      indexNames = IndexNamesHelper.getIndexNames();
    } catch (final InterruptedException exception) {
      if (_log.isErrorEnabled()) {
        _log.error("unable to append index list", exception);
      }
    }
    if (indexNames != null) {
      final Element indexNamesElement = doc.createElementNS(SearchService.NAMESPACE_SEARCH, ELEMENT_INDEX_NAMES);
      for (final String coreName : indexNames) {
        if (coreName != null) {
          final Element nameElement = doc.createElement(ELEMENT_INDEX_NAME);
          nameElement.setTextContent(coreName);
          indexNamesElement.appendChild(nameElement);
        }
      }
      doc.getDocumentElement().appendChild(indexNamesElement);
    }
  }

  /**
   * ensure and return a file upload parser.
   *
   * @return FileUpload helper.
   */
  protected synchronized ServletFileUpload getFileUploadParser() {
    if (_fileUpload == null) {
      // Create a factory for disk-based file items
      final FileItemFactory factory = new DiskFileItemFactory(Integer.MAX_VALUE, null);
      // Create a new file upload handler
      _fileUpload = new ServletFileUpload(factory);
      // Parse the request. List of FileItem
    }
    return _fileUpload;
  }

  /**
   * ensure and return a ResultDocumentBuilder.
   *
   * @return ResultDocumentBuilder helper.
   */
  protected synchronized ResultDocumentBuilder getErrorBuilder() {
    if (_errorBuilder == null) {
      _errorBuilder = new ResultDocumentBuilder();
    }
    return _errorBuilder;
  }
}
