/**
 * 
 */
package org.eclipse.smila.solr.admin;

import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.text.MessageFormat;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;
import javax.xml.stream.XMLStreamException;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.NotImplementedException;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.solr.client.solrj.SolrServerException;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.smila.datamodel.Any;
import org.eclipse.smila.datamodel.Record;
import org.eclipse.smila.datamodel.impl.DefaultDataFactoryImpl;
import org.eclipse.smila.datamodel.util.AnyUtil;
import org.eclipse.smila.datamodel.xml.XmlSerializationUtils;
import org.eclipse.smila.http.server.HttpExchange;
import org.eclipse.smila.http.server.util.ARequestHandler;
import org.eclipse.smila.http.server.util.UnsupportedMethodException;
import org.eclipse.smila.processing.parameters.MissingParameterException;
import org.eclipse.smila.solr.Activator;

/**
 * @author pwissel
 * 
 */
public class SolrAdministrationHandler extends ARequestHandler {

  /**
   * @see org.eclipse.smila.http.server.HttpHandler#handle(org.eclipse.smila.http.server.HttpExchange)
   */
  @Override
  public void handle(HttpExchange exchange) throws IOException {
    try {
      final String method = exchange.getRequestMethod();
      Any result = null;
      if (StringUtils.equalsIgnoreCase("GET", method)) {
        result = doGet(exchange);
      } else if (StringUtils.equalsIgnoreCase("POST", method)) {
        result = doPost(exchange);
      } else {
        final String msg =
          String.format("HttpMethod must be GET . HttpMethod '%s' is unsupported by SolrAdministrationHandler",
            method);
        throw new UnsupportedMethodException(msg);
      }
      sendResponse(exchange, result);
    } catch (Exception exception) {
      sendError(exchange, exception);
    }
  }

  private Any doGet(HttpExchange exchange) throws Exception {
    final GetCommand command = getGetCommand(exchange.getRequestURI());
    final SolrAdministration administration = getSolrAdministration();
    final Map<String, String[]> parameter = exchange.getParameterMap();
    Any response = null;
    switch (command) {
      case CORENAMES:
        final List<String> coreNames = administration.getCoreNames();
        response = AnyUtil.objectToAny(coreNames);
        break;
      case FIELDNAMES:
        final String core = getParameter(SolrAdministration.CORE, parameter);
        assertRequiredParameterNotNull(core, SolrAdministration.CORE);
        final List<String> fieldNames = administration.getFieldNames(core);
        response = AnyUtil.objectToAny(fieldNames);
        break;
      default:
        throw new NotImplementedException("Command: " + command);
    }
    return response;
  }

  private Any doPost(HttpExchange exchange) throws MissingParameterException, SolrAdministrationException,
    SolrServerException, IOException {
    final PostCommand command = getPostCommand(exchange.getRequestURI());
    final SolrAdministration administration = getSolrAdministration();
    final Map<String, String[]> parameter = exchange.getParameterMap();
    final String core = getParameter(SolrAdministration.CORE, parameter);
    final String other = getParameter(SolrAdministration.OTHER, parameter);
    Any response = null;
    switch (command) {
      case STATUS:
        if (core != null) {
          response = administration.status(core);
          break;
        }
        response = administration.status();
        break;
      case CREATE:
        final String name = getParameter(SolrAdministration.NAME, parameter);
        assertRequiredParameterNotNull(name, SolrAdministration.NAME);
        final String instanceDir = getParameter(SolrAdministration.INSTANCE_DIR, parameter);
        assertRequiredParameterNotNull(instanceDir, SolrAdministration.INSTANCE_DIR);
        response = administration.create(name, instanceDir, parameter);
        break;
      case RELOAD:
        assertRequiredParameterNotNull(core, SolrAdministration.CORE);
        response = administration.reload(core);
        break;
      case RENAME:
        assertRequiredParameterNotNull(core, SolrAdministration.CORE);
        assertRequiredParameterNotNull(other, SolrAdministration.OTHER);
        response = administration.rename(core, other);
        break;
      case SWAP:
        assertRequiredParameterNotNull(core, SolrAdministration.CORE);
        assertRequiredParameterNotNull(other, SolrAdministration.OTHER);
        response = administration.swap(core, other);
        break;
      case UNLOAD:
        assertRequiredParameterNotNull(core, SolrAdministration.CORE);
        final String deleteIndexString = getParameter(SolrAdministration.DELETE_INDEX, parameter);
        final boolean deleteIndex = BooleanUtils.toBoolean(deleteIndexString);
        response = administration.unload(core, deleteIndex);
        break;
      case LOAD:
        assertRequiredParameterNotNull(core, SolrAdministration.CORE);
        response = administration.load(core);
        break;
      case MERGE:
        assertRequiredParameterNotNull(core, SolrAdministration.CORE);
        final String[] sourceCore = parameter.get(SolrAdministration.SRC_CORE);
        assertRequiredParametersNotNull(sourceCore, SolrAdministration.SRC_CORE);
        response = administration.mergeIndexes(core, sourceCore);
        break;
      case CLEARCORECACHE:
        if (core != null) {
          administration.clearCoreCache(core);
          break;
        }
        administration.clearCoreCaches();
        break;
      case OPTIMIZE:
        assertRequiredParameterNotNull(core, SolrAdministration.CORE);
        response = administration.optimize(core);
        break;
      case PING:
        assertRequiredParameterNotNull(core, SolrAdministration.CORE);
        response = administration.ping(core);
        break;
      default:
        throw new NotImplementedException("Command: " + command);
    }
    return response;
  }

  private GetCommand getGetCommand(String requestUri) throws MalformedURLException {
    final List<String> dynamicUriParts = getDynamicUriParts(requestUri);
    final String command = CollectionUtils.isEmpty(dynamicUriParts) ? null : dynamicUriParts.get(0);
    if (StringUtils.isBlank(command)) {
      throw new MalformedURLException("RequestUri must contain command.");
    }
    try {
      return GetCommand.valueOf(command.toUpperCase());
    } catch (Exception exception) {
      final String allowed = StringUtils.join(GetCommand.values(), " ");
      final String msg =
        MessageFormat.format("Invalid get command: {0}. Valid commands are: {1}", command, allowed);
      throw new IllegalArgumentException(msg, exception);
    }
  }

  private PostCommand getPostCommand(final String requestUri) throws MalformedURLException {
    final List<String> dynamicUriParts = getDynamicUriParts(requestUri);
    final String command = CollectionUtils.isEmpty(dynamicUriParts) ? null : dynamicUriParts.get(0);
    if (StringUtils.isBlank(command)) {
      throw new MalformedURLException("RequestUri must contain command.");
    }
    try {
      return PostCommand.valueOf(command.toUpperCase());
    } catch (Exception exception) {
      final String allowed = StringUtils.join(PostCommand.values(), " ");
      final String msg =
        MessageFormat.format("Invalid post command: {0}. Valid commands are: {1}.", command, allowed);
      throw new IllegalArgumentException(msg, exception);
    }
  }

  private void assertRequiredParameterNotNull(String parameter, String name) throws MissingParameterException {
    if (parameter == null) {
      final String msg = MessageFormat.format("Required paramter {0} must not be null", name);
      throw new MissingParameterException(msg);
    }
  }

  private void assertRequiredParametersNotNull(String[] parameters, String name) throws MissingParameterException {
    if (ArrayUtils.isEmpty(parameters)) {
      final String msg = MessageFormat.format("Required paramter array {0} must not be null", name);
      throw new MissingParameterException(msg);
    }
  }

  private String getParameter(String name, Map<String, String[]> parameter) {
    final String[] values = parameter.get(name);
    if (ArrayUtils.isEmpty(values)) {
      return null;
    }
    return values[0];
  }

  private void sendResponse(HttpExchange exchange, Any result) throws IOException {
    final OutputStream responseStream = exchange.getResponseStream();
    final Record record = new DefaultDataFactoryImpl().createRecord();
    record.getMetadata().put("administration", result);
    final String xml = XmlSerializationUtils.serialize2string(record);
    responseStream.write(xml.getBytes("UTF-8"));
    // Didn't work for whatever reason.
    // XmlSerializationUtils.serialize2stream(record, responseStream);
    exchange.setResponseHeader("Content-Type", MimeTypes.TEXT_XML_UTF_8);
    exchange.setResponseStatus(HttpServletResponse.SC_OK);
    responseStream.flush();
  }

  /**
   * Send an error response.
   * 
   * @param exchange
   *          the {@link HttpExchange}.
   * @param exception
   *          the {@link Throwable} to send.
   * @throws IOException
   *           if {@link HttpExchange#getResponseStream()} or {@link OutputStream#write(byte[])} or
   *           {@link OutputStream#flush()} throws {@link IOException}.
   * @throws XMLStreamException
   */
  private void sendError(HttpExchange exchange, Throwable exception) throws IOException {
    final String fullStackTrace = ExceptionUtils.getFullStackTrace(exception);
    final OutputStream errorStream = exchange.getResponseStream();
    errorStream.write(fullStackTrace.getBytes());
    exchange.setResponseHeader("Content-Type", "text");
    if (exception instanceof UnsupportedMethodException || exception instanceof MissingParameterException) {
      exchange.setResponseStatus(HttpServletResponse.SC_BAD_REQUEST);
    } else {
      exchange.setResponseStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    }
    errorStream.flush();
  }

  enum PostCommand {
    STATUS, CREATE, RELOAD, RENAME, SWAP, UNLOAD, LOAD, MERGE, OPTIMIZE, PING, CLEARCORECACHE;
  }

  enum GetCommand {
    CORENAMES, FIELDNAMES;
  }

  private SolrAdministration getSolrAdministration() {
    return Activator.getInstance().getSolrManager().getSolrAdministration();
  }

}
