/*******************************************************************************
 * 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.internal.preferences.Base64;
import org.eclipse.core.resources.IFile;
import org.eclipse.wst.monitor.core.IRequest;
import org.eclipse.wst.wsi.core.internal.WSIConstants;
import org.eclipse.wst.wsi.core.internal.test.ToolInfo;
import org.eclipse.wst.wsi.core.internal.test.common.AddStyleSheet;
import org.eclipse.wst.wsi.core.internal.test.common.impl.AddStyleSheetImpl;
import org.eclipse.wst.wsi.core.internal.test.document.DocumentFactory;
import org.eclipse.wst.wsi.core.internal.test.log.Log;
import org.eclipse.wst.wsi.core.internal.test.log.LogWriter;
import org.eclipse.wst.wsi.core.internal.test.log.MessageEntry;
import org.eclipse.wst.wsi.core.internal.test.log.impl.LogImpl;
import org.eclipse.wst.wsi.core.internal.test.log.impl.LogWriterImpl;
import org.eclipse.wst.wsi.core.internal.test.log.impl.MessageEntryImpl;
import org.eclipse.wst.wsi.core.internal.test.monitor.config.Comment;
import org.eclipse.wst.wsi.core.internal.test.monitor.config.ManInTheMiddle;
import org.eclipse.wst.wsi.core.internal.test.monitor.config.MonitorConfig;
import org.eclipse.wst.wsi.core.internal.test.monitor.config.impl.CommentImpl;
import org.eclipse.wst.wsi.core.internal.test.monitor.config.impl.ManInTheMiddleImpl;

/**
 * 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 IRequest[] 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(IRequest[] requestResponses)
  {
    this.requestResponses = requestResponses;

    log = new LogImpl();
    logMonitorInformation();

    // log the messages
    for (int i=0; i<requestResponses.length; i++)
    {
      IRequest 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(IRequest rr)
  {
    if (rr != null)
    {
      byte[] request = rr.getRequest(IRequest.ALL);
      byte[] response = rr.getResponse(IRequest.ALL);
        
      String requestHeader = new String(rr.getRequest(IRequest.TRANSPORT));
      String responseHeader = new String(rr.getResponse(IRequest.TRANSPORT));
      byte[] unchunkedRequestBody = rr.getRequest(IRequest.CONTENT);
      byte[] unchunkedResponseBody = rr.getResponse(IRequest.CONTENT);
      String requestBody = null;
      String responseBody = null;

      if (unchunkedRequestBody != null)
      {
        requestBody = new String(Base64.encode(unchunkedRequestBody)); 
      }

      if (unchunkedResponseBody != null)
      {
        responseBody = new String(Base64.encode(unchunkedResponseBody)); 
      }

      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, requestBody, requestHeader);

      MessageEntry messageEntryResponse = createMessageEntry(responseId, conversationId, 
                MessageEntry.TYPE_RESPONSE, timestamp + rr.getResponseTime(), remoteHostAndPort,
                localHostAndPort, responseBody, responseHeader);
      try
      {
        if ((messageEntryRequest != null) && isMessageWithBrackets(requestBody))
        {
           if (messageEntryResponse != null)
           {
             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));
  }
      
  /**
   * 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, String messageContent, String header) 
  {
 	// Create log entry
    MessageEntry messageEntry = new MessageEntryImpl(header, messageContent);
    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);
            
    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++;
  }

  /**
   * 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(IRequest rr) 
  {
    boolean omit = false;
    if (rr != null)
    {
      String request = rr.getRequest(IRequest.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().toOSString());
      
      // 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);
  }
}
