// Copyright 2011 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.enterprise.adaptor;

import com.google.common.annotations.VisibleForTesting;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import java.util.zip.GZIPOutputStream;

/** Takes an XML feed file for the GSA, sends it to GSA and
  then reads reply from GSA. */
class GsaFeedFileSender {
  private static final Logger log
      = Logger.getLogger(GsaFeedFileSender.class.getName());
  private static final Pattern DATASOURCE_FORMAT
      = Pattern.compile("[a-zA-Z_][a-zA-Z0-9_-]*");
  private static final Pattern GROUPSOURCE_FORMAT
      = Pattern.compile("[a-zA-Z_][a-zA-Z0-9_-]*");

  // Feed file XML will not contain "<<".
  private static final String BOUNDARY = "<<";

  // Another frequently used constant of sent message.
  private static final String CRLF = "\r\n";

  private Charset gsaCharEncoding;
  private URL feedDest;
  private URL groupsDest;

  private static URL makeHandlerUrl(String host, boolean secure, String path) {
    if (null == host || null == path) {
      throw new NullPointerException();
    }
    try {
      if (secure) {
        return new URL("https://" + host + ":19902/" + path);
      } else {
        return new URL("http://" + host + ":19900/" + path);
      }
    } catch (MalformedURLException mue) {
      throw new IllegalArgumentException("invalid url", mue);
    }
  }

  GsaFeedFileSender(String host, boolean secure, Charset gsaCharSet) {
    this(makeHandlerUrl(host, secure, "xmlfeed"),
        makeHandlerUrl(host, secure, "xmlgroups"), gsaCharSet);
  }

  @VisibleForTesting
  GsaFeedFileSender(URL feedUrl, URL groupsUrl, Charset gsaCharSet) {
    if (null == gsaCharSet) {
      throw new NullPointerException();
    }
    feedDest = feedUrl;
    groupsDest = groupsUrl;
    gsaCharEncoding = gsaCharSet;
  }

  // Get bytes of string in communication's encoding.
  private byte[] toEncodedBytes(String s) {
    return s.getBytes(gsaCharEncoding);
  }

  /** Helper method for creating a multipart/form-data HTTP post.
    Creates a post parameter made of a name and value. */
  private void buildPostParameter(StringBuilder sb, String name,
      String mimetype, String value) {
    sb.append("--").append(BOUNDARY).append(CRLF);
    sb.append("Content-Disposition: form-data;");
    sb.append(" name=\"").append(name).append("\"").append(CRLF);
    sb.append("Content-Type: ").append(mimetype).append(CRLF);
    sb.append(CRLF).append(value).append(CRLF);
  }

  private byte[] buildMetadataAndUrlMessage(String datasource,
      String feedtype, String xmlDocument) {
    StringBuilder sb = new StringBuilder();
    buildPostParameter(sb, "datasource", "text/plain", datasource);
    buildPostParameter(sb, "feedtype", "text/plain", feedtype);
    buildPostParameter(sb, "data", "text/xml", xmlDocument);
    sb.append("--").append(BOUNDARY).append("--").append(CRLF);
    return toEncodedBytes("" + sb);
  }

  private byte[] buildGroupsXmlMessage(String groupsource,
      String xmlDocument) {
    StringBuilder sb = new StringBuilder();
    buildPostParameter(sb, "groupsource", "text/plain", groupsource);
    buildPostParameter(sb, "data", "text/xml", xmlDocument);
    sb.append("--").append(BOUNDARY).append("--").append(CRLF);
    return toEncodedBytes("" + sb);
  }

  /** Tries to get in touch with our GSA. */
  private HttpURLConnection setupConnection(URL url, int len,
                                            boolean useCompression)
      throws IOException {
    HttpURLConnection uc = (HttpURLConnection) url.openConnection();
    uc.setDoInput(true);
    uc.setDoOutput(true);
    if (useCompression) {
      uc.setChunkedStreamingMode(0);
      // GSA can handle gziped content, although there isn't a way to find out
      // other than just trying
      uc.setRequestProperty("Content-Encoding", "gzip");
    } else {
      uc.setFixedLengthStreamingMode(len);
    }
    uc.setRequestProperty("Content-Type",
        "multipart/form-data; boundary=" + BOUNDARY);
    return uc;
  }

  /** Put bytes onto output stream. */
  private void writeToGsa(HttpURLConnection uc, byte msgbytes[],
                          boolean useCompression)
      throws IOException {
    OutputStream outputStream = uc.getOutputStream();
    try {
      if (useCompression) {
        // setupConnection set Content-Encoding: gzip
        outputStream = new GZIPOutputStream(outputStream);
      }
      // Use copyStream(), because using a single write() prevents errors from
      // propagating during writing and causes them to be discovered at read
      // time. Using copyStream() isn't perfect either though, in that if
      // buffered data eventually causes an error, then that will still be
      // discovered at read time.
      IOHelper.copyStream(new ByteArrayInputStream(msgbytes), outputStream);
      outputStream.flush();
    } finally {
      outputStream.close();
    }
  }

  /** Get GSA's response. */
  private String readGsaReply(HttpURLConnection uc) throws IOException {
    InputStream inputStream;
    try {
      inputStream = uc.getInputStream();
    } catch (IOException ioe) {
      inputStream = uc.getErrorStream();
    }
    if (null == inputStream) {
      return null;
    }
    String reply;
    try {
      reply = IOHelper.readInputStreamToString(inputStream, gsaCharEncoding);
    } finally {
      inputStream.close();
    }
    return reply;
  }

  private void handleGsaReply(String reply, int responseCode) {
    if ("Success".equals(reply) || "success".equals(reply)) {
      log.info("success message received. code:" + responseCode);
    } else if ("Error - Unauthorized Request".equals(reply)) {
      throw new IllegalStateException("Unathorized request. "
          + "Perhaps add this machine's IP to GSA's Feeds' list "
          + "of trusted IP addresses. code:" + responseCode);
    } else {
      String msg = "HTTP code: " + responseCode + " body: " + reply;
      throw new IllegalStateException(msg);
    }
    // if ("Internal Error".equals(reply))
  }

  /**
   * Sends XML with provided datasource name and feedtype "metadata-and-url".
   * Datasource name is limited to [a-zA-Z_][a-zA-Z0-9_-]*.
   */
  void sendMetadataAndUrl(String datasource, String xmlString,
      boolean useCompression) throws IOException {
    if (!DATASOURCE_FORMAT.matcher(datasource).matches()) {
      throw new IllegalArgumentException("Data source contains illegal "
          + "characters: " + datasource);
    }
    String feedtype = "metadata-and-url";
    byte msg[] = buildMetadataAndUrlMessage(datasource, feedtype, xmlString);
    // GSA only allows request content up to 1 MB to be compressed
    if (msg.length >= 1 * 1024 * 1024) {
      useCompression = false;
    }
    sendMessage(feedDest, msg, useCompression);
  }

  /**
   * Sends XML with provided groupsource name to xmlgroups recipient.
   * Groupsource name is limited to [a-zA-Z_][a-zA-Z0-9_-]*.
   */
  void sendGroups(String groupsource, String xmlString,
      boolean useCompression) throws IOException {
    if (!GROUPSOURCE_FORMAT.matcher(groupsource).matches()) {
      throw new IllegalArgumentException("Group source is invalid: "
          + groupsource);
    }
    byte msg[] = buildGroupsXmlMessage(groupsource, xmlString);
    // GSA only allows request content up to 1 MB to be compressed
    if (msg.length >= 1 * 1024 * 1024) {
      useCompression = false;
    }
    sendMessage(groupsDest, msg, useCompression);
  }

  private void sendMessage(URL destUrl, byte msg[], boolean useCompression)
      throws IOException {
    HttpURLConnection uc = setupConnection(destUrl, msg.length, useCompression);
    uc.connect();
    try {
      writeToGsa(uc, msg, useCompression);
      String reply = readGsaReply(uc);
      handleGsaReply(reply, uc.getResponseCode());
    } catch (IOException ioe) {
      uc.disconnect();
      throw ioe;
    }
  }
}
