/*******************************************************************************
 * Copyright (c) 2002-2005 IBM Corporation 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
 *******************************************************************************/
package org.eclipse.wst.wsi.ui.internal;

import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

import org.eclipse.core.resources.IFile;
import org.eclipse.wst.internet.monitor.core.internal.provisional.Request;
import org.eclipse.wst.wsi.internal.core.WSIConstants;
import org.eclipse.wst.wsi.internal.core.ToolInfo;
import org.eclipse.wst.wsi.internal.core.common.AddStyleSheet;
import org.eclipse.wst.wsi.internal.core.common.impl.AddStyleSheetImpl;
import org.eclipse.wst.wsi.internal.core.document.DocumentFactory;
import org.eclipse.wst.wsi.internal.core.log.Log;
import org.eclipse.wst.wsi.internal.core.log.LogWriter;
import org.eclipse.wst.wsi.internal.core.log.MessageEntry;
import org.eclipse.wst.wsi.internal.core.log.MimeParts;
import org.eclipse.wst.wsi.internal.core.log.impl.LogImpl;
import org.eclipse.wst.wsi.internal.core.log.impl.LogWriterImpl;
import org.eclipse.wst.wsi.internal.core.log.impl.MessageEntryImpl;
import org.eclipse.wst.wsi.internal.core.monitor.config.Comment;
import org.eclipse.wst.wsi.internal.core.monitor.config.ManInTheMiddle;
import org.eclipse.wst.wsi.internal.core.monitor.config.MonitorConfig;
import org.eclipse.wst.wsi.internal.core.monitor.config.impl.CommentImpl;
import org.eclipse.wst.wsi.internal.core.monitor.config.impl.ManInTheMiddleImpl;
import org.eclipse.wst.wsi.internal.core.util.Utils;

/**
 * Given a list of RequestResponses from a TCPIP Monitor, 
 * this class builds a WS-I compliant Message Log file.
 * 
 * @author David Lauzon, IBM
 */
public class LogBuilder
{
  public static final String copyright = "(c) Copyright IBM Corporation 2000, 2002.";

  /**
   * IDs to identify requests and corresponding responses.
   */
  protected int conversationId = 1;

  /**
   * IDs to uniquely identify each and every message within the log file.
   */
  protected int id = 1;

  /**
   * The list of RequestResponces from a TCPIP Monitor used to generate the log file.
   */
  protected Request[] requestResponses;

  /**
   * The actual log object.
   */
  protected Log log = null;

  /**
   * The log file.
   */
  protected IFile ifile;

  /**
   * Tool information property values.
   */
  private static final String TOOL_NAME = "Monitor";
  private static final String TOOL_VERSION = "1.0";
  private static final String TOOL_RELEASE_DATE = "2003-03-20";
  private static final String TOOL_IMPLEMENTER = "IBM";
  private static final String TOOL_LOCATION = "";

  /**
   * Properties of a RequestResponse.
   */
  private static final String PROPERTY_REQUEST_HEADER = "request-header";
  private static final String PROPERTY_RESPONSE_HEADER = "response-header";
  private static final String HTTP_REQUEST_BODY = "http-request-body";
  private static final String HTTP_RESPONSE_BODY = "http-response-body";

  /**
   * Common timestamp format.
   */
  public static final SimpleDateFormat timestampFormat = new SimpleDateFormat ("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

  /**
   * Constructor.
   * @param ifile: the file handler for the log.
   */
  public LogBuilder(IFile ifile)
  {
    this.ifile = ifile;
  }

  /**
   * This builds and then returns a log based on the list of request-response pairs.
   * @param requestResponses: a list of messages in the form of request-response pairs.
   * @return a log based on a list of request-response pairs.
   */
  public Log buildLog(Request[] requestResponses)
  {
    this.requestResponses = requestResponses;

    log = new LogImpl();
    logMonitorInformation();

    // log the messages
    for (int i=0; i<requestResponses.length; i++)
    {
      Request rr = requestResponses[i];
      if ((rr != null) && (!omitRequestResponse(rr)))
      {
        logRequestResponse(rr);
      }
    }
    return log;
  }

  /**
   * Currently a no-op.
   */
  public void logMonitorInformation()
  {
  }

  /**
   * Log the request-response pair.
   *@param rr: a request-response pair.
   */
  protected void logRequestResponse(Request rr)
  {
    if (rr != null)
    {
      byte[] request = rr.getRequest(Request.ALL);
      byte[] response = rr.getResponse(Request.ALL);
        
      String requestHeader = new String(rr.getRequest(Request.TRANSPORT));
      String responseHeader = new String(rr.getResponse(Request.TRANSPORT));
      
      byte[] unchunkedRequestBody = rr.getRequest(Request.CONTENT);
      byte[] unchunkedResponseBody = rr.getResponse(Request.CONTENT);
 
      long timestamp = rr.getDate().getTime();
      String localHostAndPort = "localhost:" + rr.getLocalPort();
      String remoteHostAndPort = rr.getRemoteHost() + ":" + rr.getRemotePort();

      int requestId  = getNextAvailableId();
      int responseId = getNextAvailableId();
      int conversationId = getNextAvailableConversationId();

      MessageEntry messageEntryRequest = createMessageEntry(requestId, conversationId, 
                MessageEntry.TYPE_REQUEST, timestamp, localHostAndPort,
                remoteHostAndPort, unchunkedRequestBody, requestHeader);

      MessageEntry messageEntryResponse = createMessageEntry(responseId, conversationId, 
                MessageEntry.TYPE_RESPONSE, timestamp + rr.getResponseTime(), remoteHostAndPort,
                localHostAndPort, unchunkedResponseBody, responseHeader);
      try
      {
        if ((messageEntryRequest != null) &&
            (messageEntryResponse != null) &&
            ((messageEntryRequest.isMimeContent()) ||
			 (isMessageWithBrackets(messageEntryRequest.getMessage()))))
        {
                log.addLogEntry(messageEntryRequest);
               log.addLogEntry(messageEntryResponse);
        }
      }
      catch (Exception e)
      {
        // ignore the request response pair
      }
    }
  }

  /**
   * Returns true if the content of the message has at least
   * one left and one right bracket.
   * @param message: a message content.
   * @return true if the content of the message has at least
   *         one left and one right bracket.
   */
  public boolean isMessageWithBrackets(String message)
  {
    return ((message != null) && 
            (message.indexOf("<")!= -1) && 
            (message.indexOf(">") != -1));
  }
  /**
   * Returns the header of a message.
   * @param requestOrResponse: a message.
   * @param headerLength: the length of the header in the message.
   * @return the header of a message.
   */ 
  protected String getHeader(byte[] requestOrResponse,  int headerLength)
  {
    String result = null;
    
    if ((requestOrResponse != null) && 
        (headerLength > 0) && 
        (requestOrResponse.length >= headerLength))
    {
      byte[] header = new byte[headerLength];
      System.arraycopy(requestOrResponse, 0, header, 0, headerLength);
      result = new String(header);
    }
    return result;
  }

  /**
   * Returns the body of a message.
   * @param requestOrResponse: a message.
   * @param headerLength: the length of the header in the message.
   * @return the body of a message.
   */ 
  protected String getBody(byte[] requestOrResponse,  int headerLength)
  {
    String result = null;
    
    if ((requestOrResponse != null) && 
        (headerLength > 0) && 
        (requestOrResponse.length > headerLength))
    {
      int bodyLength = requestOrResponse.length - headerLength;
      byte[] body = new byte[bodyLength];
      System.arraycopy(requestOrResponse, headerLength, body, 0, bodyLength);
      result = new String(body);
    }
    return result;
  }
      
  /**
   * Create a log entry.
   * @param id: unique message id within the log.
   * @param conversationId: conversation id to identify request-response pairs.
   * @param type: type indicating a request or response.
   * @param timestamp: the date and time of the message.
   * @param senderHostAndPort: the host and port of the sender.
   * @param receiverHostAndPort: the host and port of the receiver.
   * @param messageContent: the content or body of the message.
   * @param header: the header of the message.
   * @return a log entry.
   */
  protected MessageEntry createMessageEntry(int id, int conversationId, String type, long timestamp, 
        String senderHostAndPort, String receiverHostAndPort, byte[] messageContent, String header) 
  {
 	// Create log entry
    MessageEntry messageEntry = new MessageEntryImpl();
    messageEntry.setId(String.valueOf(id));
    messageEntry.setConversationId(String.valueOf(conversationId));
    messageEntry.setType(type);
    messageEntry.setTimestamp(getTimestamp(new Date(timestamp)));
    messageEntry.setSenderHostAndPort(senderHostAndPort);
    messageEntry.setReceiverHostAndPort(receiverHostAndPort);
    messageEntry.setEncoding(WSIConstants.DEFAULT_XML_ENCODING);
    
    messageEntry.setHTTPHeaders(header);

    if (Utils.isMultipartRelatedMessage(header))
    {
    	MimeParts mimeParts = Utils.parseMultipartRelatedMessage(messageContent, header, WSIConstants.DEFAULT_XML_ENCODING);
    	if (mimeParts == null)
    	{
    	  // problem creating Mimeparts -- treat it as simple SOAP message
    	  messageEntry.setMessage(new String(messageContent));
    	  messageEntry.setMimeContent(false);
    	}
    	else
    	{
          messageEntry.setMimeParts(mimeParts);
          messageEntry.setMimeContent(true);
    	}
    }
    else
    {
      // Get the message content
      messageEntry.setMessage(new String(messageContent));
      messageEntry.setMimeContent(false);
    }
    return messageEntry;
  }

  /**
   * Returns the next available id, then increments the id value.
   * @return the next available id.
   */
  protected int getNextAvailableId()
  {
    return id++;
  }

  /**
   * Returns the next available conversation id, then increments the conversation id value.
   * A conversation id identfies a request and its corresponding response.
   * @return the next available converasationid.
   */
  protected int getNextAvailableConversationId()
  {
    return conversationId++;
  }

  public int getHeaderLength(Integer obj)
  {
    int result = 0;
    if (obj != null)
    {
      result = obj.intValue();
    }
    return result;
  }

  /**
   * Check for HTTP messages that should not be logged.
   * @param rr: a request-response pair.
   * @return true if the request-response pair should be omitted from the log.
   */
  private boolean omitRequestResponse(Request rr) 
  {
    boolean omit = false;
    if (rr != null)
    {
      String request = rr.getRequest(Request.TRANSPORT).toString();
      if ((request != null) &&
          ((request.startsWith("CONNECT")) ||
           (request.startsWith("TRACE")) || 
           (request.startsWith("DELETE")) || 
           (request.startsWith("OPTIONS")) || 
           (request.startsWith("HEAD"))))
      { 
        omit = true;
      }
    }
    return omit;
  }

  /**
   * Write log out to file.
   * @param log: log to be written to file.
   */

  public void writeLog(Log log)
  {
    try
    {
      // Get log writer
      LogWriter logWriter = new LogWriterImpl();
    
      logWriter.setWriter(ifile.getLocation().toString());
      
      // Write start of log file
      logWriter.write(new StringReader(log.getStartXMLString("")));
    
      // Write monitor tool information
      String monitorInfo = generateMonitorToolInfo();
      logWriter.write(new StringReader(monitorInfo));

      for (int i=0; i<log.getEntryCount(); i++)
      {
        MessageEntry me = log.getLogEntry(i);
        logWriter.write(new StringReader(me.toXMLString("")));
      }
      logWriter.write(new StringReader(log.getEndXMLString("")));
      logWriter.close();
    }
    catch (Exception e)
    {
      System.out.println("Exception thrown when printing log file.");
    }
  }


  /**
   * Returns XML string representation of the Monitor tool.
   * @return XML string representation of the Monitor tool.
   */
  protected String generateMonitorToolInfo()
  {

    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw); 

    try
    {
      // Tool information
      ToolInfo toolInfo = new ToolInfo(TOOL_NAME, TOOL_VERSION, TOOL_RELEASE_DATE, TOOL_IMPLEMENTER, TOOL_LOCATION);

      DocumentFactory documentFactory = DocumentFactory.newInstance();
      MonitorConfig monitorConfig = documentFactory.newMonitorConfig();
    
      Comment comment = new CommentImpl();
      comment.setText("Comment");
      monitorConfig.setComment(comment);
      monitorConfig.setLogLocation("URL");
      monitorConfig.setReplaceLog(true);

      AddStyleSheet addStyleSheet = new AddStyleSheetImpl();
      monitorConfig.setAddStyleSheet(addStyleSheet);

      monitorConfig.setLogDuration(600);
      monitorConfig.setTimeout(3);
     
      ManInTheMiddle manInTheMiddle = new ManInTheMiddleImpl();
      monitorConfig.setManInTheMiddle(manInTheMiddle);

      monitorConfig.setLocation("documentURI");
      monitorConfig.setVerboseOption(false);

      // Start     
      pw.print(toolInfo.getStartXMLString(""));
    
      // Config
      pw.print(monitorConfig.toXMLString(WSIConstants.NS_NAME_WSI_MONITOR_CONFIG));

      // End
      pw.println(toolInfo.getEndXMLString(""));
    }
    catch (Exception e)
    {
    }
    return sw.toString();
  }

  /**
   * Get the given date and time as a timestamp.
   * @param date: a date object.
   * @return the given date and time as a timestamp.
   */
  public static String getTimestamp(Date date)
  {
    timestampFormat.setTimeZone(TimeZone.getDefault());
    return timestampFormat.format(date);
  }
}
