/*******************************************************************************
 * Copyright (c) 2002-2003 IBM Corporation, Beacon Information Technology Inc. and others.
 * 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:
 *   IBM      - Initial API and implementation
 *   BeaconIT - Initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.wsi.internal.core.monitor;

import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;

import org.eclipse.wst.wsi.internal.core.WSIConstants;
import org.eclipse.wst.wsi.internal.core.WSIException;
import org.eclipse.wst.wsi.internal.core.log.MessageEntry;
import org.eclipse.wst.wsi.internal.core.util.Utils;

/**
 * Socket Handler.
 * 
 * @author Peter  Brittenham (peterbr@us.ibm.com)
 * @version 1.0.1
 */
public class SocketHandler extends Thread
{
  protected SocketConnection socketConnection;
  protected SocketHandler pairedSocketHandler;
  protected String connectionType;
  protected int conversationID;
  protected String targetHost;
  protected int readTimeoutSeconds;

  protected Socket inSocket;
  protected Socket outSocket;
  protected InputStream inputStream = null;
  protected OutputStream outputStream = null;

  protected boolean verbose = false;

  protected boolean readTimedOut = false;

  // I18N: 2003.02.26 modified by K.Nakagome@BeaconIT
  private String mimeCharset = null;
  private String xmlEncoding = null;

  protected static final String CRLF = "\r\n";

  protected static final String HTTP_100_CONTINUE =
    "100 Continue".toUpperCase();
  protected static final String CHUNKED =
    "Transfer-Encoding: chunked".toUpperCase();
  protected static final String CHUNKED_WITH_QUOTES =
    "Transfer-Encoding: \"chunked\"".toUpperCase();
  protected static final String CONTENT_LENGTH =
    "Content-Length:".toUpperCase();

  /**
   * Create socket handler.
   * @param socketConnection   socket connection.
   * @param connectionType     connection type.
   * @param conversationID     conversation id.
   * @param targetHost         target host.
   * @param inSocket           in socket.
   * @param outSocket          out socket.
   * @param readTimeoutSeconds read timeout seconds.
   */
  public SocketHandler(
    SocketConnection socketConnection,
    String connectionType,
    int conversationID,
    String targetHost,
    Socket inSocket,
    Socket outSocket,
    int readTimeoutSeconds)
  {
    this.socketConnection = socketConnection;
    this.connectionType = connectionType;
    this.conversationID = conversationID;
    this.targetHost = targetHost;
    this.inSocket = inSocket;
    this.outSocket = outSocket;
    this.readTimeoutSeconds = readTimeoutSeconds;

    // ADD:
    verbose =
      socketConnection.getMonitor().getMonitorConfig().getVerboseOption();

    start();
  }

  /**
   * Set paired socket handler.
   * @param pairedSocketHandler paired socket handler.
   */
  public void setPairedSocketHandler(SocketHandler pairedSocketHandler)
  {
    this.pairedSocketHandler = pairedSocketHandler;
  }

  /**
   * Send the data from the input socket to the output socket.
   */
  public void run()
  {
    int readLen;
    String readMsg;
    MessageContext messageContext = null;

    // Create read buffer      
    byte[] readBuffer = new byte[4096];

    try
    {
      // Get the input and output streams
      this.inputStream = this.inSocket.getInputStream();
      this.outputStream = this.outSocket.getOutputStream();

      // Process while the connection is active 
      // (NOTE: there might be more than 1 message per connection)
      boolean connectionActive = true;
      while (connectionActive)
      {
        // Reset all data
        readLen = 0;
        messageContext = new MessageContext();

        // Read until message is complete
        boolean messageComplete = false;
        while (!messageComplete)
        {
          try
          {
            // DEBUG:
            debug("run", "Read data from the input stream.");

            // Read data from the input stream
            readLen = inputStream.read(readBuffer, 0, readBuffer.length);

            // Reset read timeout flag
            readTimedOut = false;

            // DEBUG:
            debug("run", "readLen: " + readLen);

            if (readLen == -1)
            {
              connectionActive = false;
              messageComplete = true;
            }

            // If data was read, then check for 100 continue
            else if (readLen > 0)
            {
              // If this is the first data that was read, then get the timestamp
              if (messageContext.timestamp == null)
                messageContext.timestamp = Utils.getTimestamp();

              if (connectionType.equals(MessageEntry.TYPE_REQUEST))
              {
                byte[] toHost =
                  new String(
                    socketConnection.redirect.getToHost()
                      + ":"
                      + socketConnection.redirect.getToPort())
                    .getBytes();

                String message = new String(readBuffer, 0, readLen);

                int index = message.indexOf(CRLF + "Host: ");
                if (index > -1)
                {
                  index += 8;
                  int secondPart = message.indexOf(CRLF, index);

                  // Write the data to the output stream and then go format it
                  write(this.outputStream, readBuffer, 0, index);
                  write(this.outputStream, toHost, 0, toHost.length);
                  write(
                    this.outputStream,
                    readBuffer,
                    secondPart,
                    readLen - secondPart);
                }
                else
                {
                  // Write the data to the output stream and then go format it
                  write(this.outputStream, readBuffer, 0, readLen);
                }
              }
              else
              {
                // Write the data to the output stream and then go format it
                write(this.outputStream, readBuffer, 0, readLen);
              }

              // DEBUG:
              if (verbose)
              {
                String bufferString = new String(readBuffer, 0, readLen);
                debug("run", "buffer as string: [" + bufferString + "]");
                if (bufferString.length() <= 50)
                  debug(
                    "run",
                    "buffer as hexstring: ["
                      + Utils.toHexString(bufferString)
                      + "]");
                else
                  debug(
                    "run",
                    "buffer as hexstring: ["
                      + Utils.toHexString(bufferString.substring(0, 50))
                      + " ...]");
              }

              // See if this part of the buffer contains the BOM
              if (messageContext.bom == 0)
              {
                messageContext.bom = getBOM(readBuffer);
              }

              // DEBUG
              debug("run", "bom: " + messageContext.bom);

              String encoding;

              try
              {
                encoding = getEncoding();
                readMsg =
                  new String(
                    readBuffer,
                    0,
                    readLen,
                    Utils.getJavaEncoding(encoding));
                setEncoding(readMsg);
                if (!encoding.equals(getEncoding()))
                {
                  encoding = getEncoding();
                  readMsg =
                    new String(
                      readBuffer,
                      0,
                      readLen,
                      Utils.getJavaEncoding(encoding));
                }
              }

              catch (UnsupportedEncodingException uee)
              {
                debug("run", "EXCEPTION (3): " + uee.toString());
                throw new RuntimeException(uee.toString());
              }

              // Set encoding in the message context
              messageContext.encoding = encoding;

              // DEBUG
              debug("run", "encoding: " + messageContext.encoding);

              // Process message
              messageContext = processMessage(readLen, readMsg, messageContext);
            }

            // If message is complete, then log it and reset buffer
            if ((isMessageComplete(messageContext))
              || ((readLen == -1) && (messageContext.messageBuffer.length() > 0)))
            {
              // Log message
              logMessage(messageContext);

              // Set message complete
              messageComplete = true;
            }
          }

          catch (InterruptedIOException ie)
          {
            // Set read timeout flag
            readTimedOut = true;

            debug("run", "InterruptedIOException: " + ie.toString());

            // If the read is not done, then shutdown 
            if (pairedSocketHandler != null
              && pairedSocketHandler.isReadWaiting()
              && pairedSocketHandler.isReadTimedOut())
            {
              // DEBUG:
              debug("run", "read timed out on both sockets");

              // If there is data in the message buffer and it is complete, then log it
              if ((isMessageComplete(messageContext))
                || (messageContext.messageBuffer.length() > 0))
              {
                // Log message
                logMessage(messageContext);
              }

              // Set message complete
              connectionActive = false;
              messageComplete = true;
            }
          }

          catch (Exception e2)
          {
            // DEBUG:
            debug(
              "run",
              "EXCEPTION (2): "
                + e2.toString()
                + "\n"
                + Utils.getExceptionDetails(e2));
            //e2.printStackTrace();

            // If there is data in the message buffer and it is complete, then log it
            if ((isMessageComplete(messageContext))
              || (messageContext.messageBuffer.length() > 0))
            {
              // Log message
              logMessage(messageContext);
            }

            // Set message complete
            connectionActive = false;
            messageComplete = true;
          }
        }
      }
    }

    catch (Exception e)
    {
      // DEBUG:
      debug(
        "run",
        "EXCEPTION (1): "
          + e.getMessage()
          + "\n"
          + Utils.getExceptionDetails(e));
      //e.printStackTrace();
    }

    catch (Error err)
    {
      // DEBUG:
      debug("run", "ERROR: " + err.getMessage());
      //err.printStackTrace();
    }

    finally
    {
      shutdown();
      socketConnection.wakeUp();
    }
  }

  /**
   * Process the message.
   */
  private MessageContext processMessage(
    int readLen,
    String readMsg,
    MessageContext inMessageContext)
    throws WSIException
  {
    boolean continueRead = false;

    // Initialize message context                                       
    MessageContext messageContext = inMessageContext;

    // Get message buffer and chunked data from message context
    StringBuffer messageBuffer = messageContext.messageBuffer;
    ChunkedData chunkedData = messageContext.chunkedData;

    // If all we received was the header with 100 continue, then ignore it
    if ((readMsg.toUpperCase().indexOf(HTTP_100_CONTINUE) != -1)
      && (readLen >= 25))
    {
      // DEBUG:
      debug("processMessage", "Ignore HTTP 100 Continue.");

      // Find the end of the HTTP 100 message
      int index = Utils.getFirstCRLFCRLF(readMsg);

      // If there is only the HTTP 100 message, then just ignore it
      if (index == readMsg.length())
        continueRead = true;

      // Otherwise remove the HTTP 100 message and continue
      else
        readMsg = readMsg.substring(index);
    }

    // ADD: What if a bypassed message contains another message after it?
    if (!continueRead && bypassMessage(readMsg))
    {
      // DEBUG:
      debug(
        "processMessage",
        "Do not log message as defined in the monitor spec, but it will be sent.");

      continueRead = true;
    }

    if (!continueRead)
    {
      int index = 0;

      // If there is chunked data, then get the length
      if ((readMsg.toUpperCase().indexOf(CHUNKED) != -1)
        || (readMsg.toUpperCase().indexOf(CHUNKED_WITH_QUOTES) != -1))
      {
        // DEBUG:
        debug("processMessage", "Processing chunked data...");

        // Get the location of the first CFLF
        if ((index = readMsg.indexOf(CRLF + CRLF)) == -1)
        {
          throw new WSIException("Could not locate end of HTTP header.");
        }

        // Include the CRLF+CRLF in the index
        index += 4;

        // DEBUG:
        debug(
          "processMessage",
          "Add header before decoding chunked data: ["
            + readMsg.substring(0, index)
            + "]");

        // Add HTTP header to buffer
        messageBuffer.append(readMsg.substring(0, index));

        // If there is no more data (i.e. header only), then just indicate that there is more chunked data
        if (readMsg.length() == index)
        {
          chunkedData = new ChunkedData(this, true);

          // DEBUG:
          debug(
            "processMessage",
            "There is chunk data, but none in this part of the message.");
        }

        // Determine if the remainder of the data is complete (i.e. ends with [0][CRLF][Optional Footer][CRLF])
        else
        {
          // Create chunked data object
          chunkedData = new ChunkedData(this, readMsg.substring(index));

          if (!chunkedData.isMoreChunkedData())
          {
            chunkedData.decodeAndAddDataToBuffer(messageBuffer);
          }
        }
      }

      else if (chunkedData != null && chunkedData.isMoreChunkedData())
      {
        // DEBUG:
        debug("processMessage", "Processing MORE chunked data...");

        // Add data
        chunkedData.addData(readMsg);

        // Decode data
        if (!chunkedData.isMoreChunkedData())
        {
          chunkedData.decodeAndAddDataToBuffer(messageBuffer);
        }
      }

      // Else just append the data to the buffer
      else
      {
        // DEBUG:
        debug(
          "processMessage",
          "Add data to message entry buffer: [" + readMsg + "]");

        messageBuffer.append(readMsg);
      }
    }

    // Set updated message buffer and chunked data in message context    
    messageContext.messageBuffer = messageBuffer;
    messageContext.chunkedData = chunkedData;

    // Return message context 
    return messageContext;
  }

  /**
   * Shutdown input socket and close input stream.
   * @param inSocket in socket.
   * @param inputStream input stream.
   */
  protected void stopInput(Socket inSocket, InputStream inputStream)
  {
    try
    {
      // If there is a input socket, then shutdown the input
      if (inSocket != null)
      {
        inSocket.shutdownInput();
      }

      // If there is an input stream then close it
      if (inputStream != null)
      {
        inputStream.close();
      }
    }
    catch (Exception e)
    {
      // Ignore since we are stopping everything
    }

    inputStream = null;
  }

  /**
   * Shutdown output socket and close output stream.
   * @param outSocket out socket.
   * @param outputStream output stream.
   */
  protected void stopOutput(Socket outSocket, OutputStream outputStream)
  {
    try
    {
      // If there is an output stream, then flush it
      if (outputStream != null)
      {
        outputStream.flush();
      }

      // If there is a input socket, then shutdown the input
      if (outSocket != null)
      {
        outSocket.shutdownOutput();
      }

      // If there is an output stream then close it
      if (outputStream != null)
      {
        outputStream.close();
      }
    }

    catch (Exception e)
    {
      // Ignore since we are stopping everything
    }

    outputStream = null;
  }

  /**
   * Shutdown handler.
   */
  public void shutdown()
  {
    // Stop both the input and output
    stopInput(this.inSocket, this.inputStream);
    stopOutput(this.outSocket, this.outputStream);
  }

  /**
   * Display debug messages.
   */
  void debug(String method, String message)
  {
    debug("SocketHandler", method, message);
  }

  /**
   * Display debug messages.
   */
  void debug(String className, String method, String message)
  {
    if (verbose)
      print(className, method, message);
  }

  /**
   * Display messages.
   */
  void print(String className, String method, String message)
  {
    System.out.println(
      "["
        + Thread.currentThread().getName()
        + "] ["
        + className
        + "."
        + method
        + "] ["
        + this.connectionType
        + "] "
        + message);
  }

  /** 
   * Write data.
   */
  private void write(
    OutputStream outputStream,
    byte[] buffer,
    int start,
    int length)
    throws IOException
  {
    if (outputStream == null)
    {
      // DEBUG:
      debug("write", "Could not write buffer because output stream is null.");
    }
    else
    {
      // DEBUG:
      debug("write", "buffer: [" + new String(buffer, start, length) + "]");

      outputStream.write(buffer, start, length);
    }
  }

  /** 
   * Check if message is complete.
   * 
   * @param messageContext
   */
  private boolean isMessageComplete(MessageContext messageContext)
    throws WSIException
  {
    int index, index2, contentLen;
    boolean messageComplete = false;

    boolean moreChunkedData = messageContext.chunkedData.isMoreChunkedData();

    String message = messageContext.messageBuffer.toString();

    // Find the first CRLF + CRLF which marks the end of the HTTP header
    String httpHeader;
    index = Utils.getFirstCRLFCRLF(message);
    if (index == -1)
      httpHeader = message;
    else
      httpHeader = message.substring(0, index);

    // If chunked data, then complete only if there is no more data
    if (((httpHeader.toUpperCase().indexOf(CHUNKED) != -1)
      || (httpHeader.toUpperCase().indexOf(CHUNKED_WITH_QUOTES) != -1))
      && (!moreChunkedData))
    {
      debug(
        "isMessageComplete",
        "HTTP header indicates chunked data and there is no more chunked data");
      messageComplete = true;
    }

    // Check for content length
    else if ((index = httpHeader.toUpperCase().indexOf(CONTENT_LENGTH)) == -1)
    {
      debug("isMessageComplete", "HTTP header does not contain content length");

      // Should not have complete POST header without content length
      if (httpHeader.startsWith("POST"))
      {
        if (httpHeader.endsWith(CRLF + CRLF))
        {
          throw new WSIException("Could not locate content-length in HTTP POST header.");
        }

        messageComplete = false;
      }

      // This could be a GET, so see if the the complete header has been received
      else if (
        httpHeader.startsWith("GET")
          && (message.length() == httpHeader.length()
            && message.endsWith(CRLF + CRLF)))
      {
        messageComplete = true;
      }

      else
      {
        messageComplete = false;
      }
    }

    // If there is content length, then see if the entire message has been received
    else if ((index = httpHeader.toUpperCase().indexOf(CONTENT_LENGTH)) != -1)
    {
      // Find end of content length value
      index2 = httpHeader.indexOf(CRLF, index);

      debug("isMessageComplete", "CRLF: " + Utils.toHexString(CRLF));
      debug(
        "isMessageComplete",
        "httpHeader/index: " + Utils.toHexString(httpHeader.substring(index)));

      // Get content length
      contentLen =
        Integer
          .decode(
            httpHeader.substring(index + CONTENT_LENGTH.length() + 1, index2))
          .intValue();

      // DEBUG:
      debug("isMessageComplete", "contentLen: " + contentLen);

      // Find the first CRLF + CRLF which marks the end of the HTTP header
      index = Utils.getFirstCRLFCRLF(message);

      // DEBUG:
      debug(
        "isMessageComplete",
        "actual received message length: " + (message.length() - (index)));

      // If content length is equal to actual message content length, then message is complete
      if (contentLen == message.length() - index)
      {
        messageComplete = true;

        // DEBUG:
        debug(
          "isMessageComplete",
          "contentLen = actual received message length.");
      }
    }

    // Message is not complete
    else
    {
      messageComplete = false;
    }

    // DEBUG:
    debug("isMessageComplete", "messageComplete: " + messageComplete);

    return messageComplete;
  }

  /** 
   * Log message.
   * 
   * @param messageBuffer
   */
  private void logMessage(MessageContext messageContext) throws WSIException
  {
    MessageEntry messageEntry = null;

    // Determine sender and receiver host/port
    String senderHostAndPort, receiverHostAndPort;

    // Request
    if (connectionType.equals(MessageEntry.TYPE_REQUEST))
    {
      senderHostAndPort =
        inSocket.getInetAddress().getHostAddress() + ":" + inSocket.getPort();
      receiverHostAndPort = targetHost + ":" + outSocket.getPort();
    }

    // Response      
    else
    {
      senderHostAndPort = targetHost + ":" + inSocket.getPort();
      receiverHostAndPort =
        outSocket.getInetAddress().getHostAddress() + ":" + outSocket.getPort();
    }

    // Create message entry
    this.socketConnection.logMessage(
      conversationID,
      this.connectionType,
      messageContext.timestamp,
      senderHostAndPort,
      receiverHostAndPort,
      messageContext.messageBuffer,
      messageContext.bom,
      messageContext.encoding);
  }

  /**
   * Check for HTTP messages that should not be logged.
   */
  private boolean bypassMessage(String message)
  {
    boolean bypass = false;
    if ((message.startsWith("CONNECT"))
      || (message.startsWith("TRACE"))
      || (message.startsWith("DELETE"))
      || (message.startsWith("OPTIONS"))
      || (message.startsWith("HEAD")))
    {
      bypass = true;
    }

    return bypass;
  }

  // I18N: 2003.02.26 modified by K.Nakagome@BeaconIT
  /**
   * Set Encoding Parameters
   * @param messageFragment String of a HTTP message fragment.
   * @author K.Nakagome@BeaconIT Japan SIG 
   */
  private void setEncoding(String messageFragment)
  {
    if (mimeCharset == null || mimeCharset.length() == 0)
    {
      mimeCharset = Utils.getHTTPCharset(messageFragment);
    }
    if (xmlEncoding == null || xmlEncoding.length() == 0)
    {
      xmlEncoding = Utils.getXMLEncoding(messageFragment);
    }
    return;
  }

  // I18N: 2003.02.26 modified by K.Nakagome@BeaconIT
  /**
   * Get Encoding Parameter
   * @return Character encoding of HTTP message.
   * @author K.Nakagome@BeaconIT Japan SIG 
   */
  private String getEncoding()
  {
    String encoding = WSIConstants.DEFAULT_XML_ENCODING;
    if (mimeCharset != null && mimeCharset.length() > 0)
    {
      encoding = mimeCharset;
    }
    if (xmlEncoding != null && xmlEncoding.length() > 0)
    {
      encoding = xmlEncoding;
    }
    return encoding;
  }

  /**
   * Get the Byte Order Mark from the message (if there is one).
   */
  private int getBOM(byte[] message)
  {
    int bom = 0;

    byte FF = (byte) 0xFF;
    byte FE = (byte) 0xFE;
    byte EF = (byte) 0xEF;
    byte BB = (byte) 0xBB;
    byte BF = (byte) 0xBF;

    // Search through the byte array for CRLF+CRLF.  This will mark the end of the header.
    int i = Utils.getFirstCRLFCRLF(message, 0);
    if (i != -1)
    {
      // DEBUG:
      debug(
        "getBOM",
        "message[i]: "
          + message[i]
          + ", message[i+1]: "
          + message[i+1]);

      // Check for UTF-8 BOM
      if (((i + 2) < message.length)
        && message[i] == EF
        && message[i+1] == BB
        && message[i+2] == BF)
      {
        bom = 0xEFBBBF;
      }
      // Check for UTF-16 big-endian BOM
      else if (
        ((i+1) < message.length)
          && message[i] == FE
          && message[i + 1] == FF)
      {
        bom = 0xFEFF;
      }
      // Check for UTF-16 little-endian BOM
      else if (
        ((i+1) < message.length)
          && message[i] == FF
          && message[i+1] == FE)
      {
        bom = 0xFFFE;
      }
      // ADD: Do we need to check for other BOMs
    }
    return bom;
  }

  /**
   * Determine if the read is still waiting for data.
   */
  boolean isReadWaiting()
  {
    boolean readWaiting = false;

    try
    {
      // DEBUG:
      debug(
        "isReadWaiting",
        "inSocket.getInputStream().available(): "
          + inSocket.getInputStream().available());

      if (inSocket.getInputStream().available() == 0)
      {
        readWaiting = true;
      }
    }

    catch (IOException ioe)
    {
    }

    return readWaiting;
  }

  /**
   * Get read timed out flag.
   */
  boolean isReadTimedOut()
  {
    return this.readTimedOut;
  }

  /**
   * Message context contains information about the message that is being processed.
   */
  class MessageContext
  {
    StringBuffer messageBuffer;
    ChunkedData chunkedData;
    String timestamp;
    int bom;
    String encoding;

    /**
     * Create new message context.
     */
    MessageContext()
    {
      messageBuffer = new StringBuffer();
      chunkedData = new ChunkedData();
      timestamp = null;
      bom = 0;
      encoding = WSIConstants.DEFAULT_XML_ENCODING;
    }
  }
}
