/*******************************************************************************
 * 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.internal.core.log.impl;

import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import org.eclipse.wst.wsi.internal.core.ToolEnvironment;
import org.eclipse.wst.wsi.internal.core.ToolInfo;
import org.eclipse.wst.wsi.internal.core.WSIConstants;
import org.eclipse.wst.wsi.internal.core.WSIException;
import org.eclipse.wst.wsi.internal.core.log.LogReader;
import org.eclipse.wst.wsi.internal.core.log.MessageEntry;
import org.eclipse.wst.wsi.internal.core.log.MessageEntryHandler;
import org.eclipse.wst.wsi.internal.core.log.MimePart;
import org.eclipse.wst.wsi.internal.core.log.MimeParts;
import org.eclipse.wst.wsi.internal.core.monitor.config.Comment;
import org.eclipse.wst.wsi.internal.core.monitor.config.impl.CommentImpl;
import org.eclipse.wst.wsi.internal.core.profile.validator.EntryContext;
import org.eclipse.wst.wsi.internal.core.report.ArtifactReference;
import org.eclipse.wst.wsi.internal.core.report.Entry;
import org.eclipse.wst.wsi.internal.core.report.impl.ArtifactReferenceImpl;
import org.eclipse.wst.wsi.internal.core.report.impl.EntryImpl;
import org.eclipse.wst.wsi.internal.core.util.EntryType;
import org.eclipse.wst.wsi.internal.core.util.Utils;
import org.eclipse.wst.wsi.internal.core.xml.XMLUtils;
import org.eclipse.wst.wsi.internal.core.xml.dom.ElementLocation;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

/**
 * Defines the implementation used to read the Log file.
 * 
 * @version 1.0.1
 * @author Neil Delima (nddelima@ca.ibm.com)
 * @author Peter Brittenham (peterbr@us.ibm.com)
 * @author Graham Turrell (gturrell@uk.ibm.com)
 */
public class LogReaderImpl implements LogReader
{
  /**
   * Document location.
   */
  private String documentURI;

  /** Used to ensure that the implementer is the first element after the log element **/
  private int firstLogElement = 0;
  private int elementCount = 0;
  private boolean bMonitorFirst = false;

  private WSIException wsiException = null;

  /**
   * @see org.eclipse.wst.wsi.internal.core.log.LogReader#readLog(String, LogEntryHandler)
   */
  public void readLog(String logURI, MessageEntryHandler logReaderCallback)
    throws WSIException
  {
    // Read the log file entries
    readLog(new InputSource(logURI), logReaderCallback);
  }

  /**
   * @see org.eclipse.wst.wsi.internal.core.log.LogReader#readLog(Reader, LogEntryHandler)
   */
  public void readLog(Reader reader, MessageEntryHandler logReaderCallback)
    throws WSIException
  {
    // Read the log file entries
    readLog(new InputSource(reader), logReaderCallback);
  }

  /**
   * Read and parse the log file.
   * @param inputSource          an InputSource object
   * @param messageEntryHandler  a MessageEntryHandler object
   * @throws WSIException if a problem occurs while reading the log file.
   */
  protected void readLog(
    InputSource inputSource,
    MessageEntryHandler messageEntryHandler)
    throws WSIException
  {
    try
    {
      // Get the XML reader
      XMLReader xmlReader = XMLUtils.getXMLReader();

      /** TO DO:  The LogFile must be valid wrt its schema.  The schemaLocation probably
       * needs to be set in some properties file.
       * These two are to turn on validation 
      reader.setFeature(FEATURE_VALIDATION,true);
      */

      // Set the content handler
      xmlReader.setContentHandler(new LogFileHandler(messageEntryHandler));

      // Start parsing the file
      xmlReader.parse(inputSource);

      // ADD: Need to find a way to determine when this exception should be thrown, 
      // since by the time we get here all of the test assertions have been processed.
      // Also, only the last exception is propogated back.  Should all of the exceptions
      // be captured and propogated back?
      if (wsiException != null)
      {
        // TEMP: For now, don't throw the exception
        //throw wsiException;
      }

      //Requirement, the monitor MUST be the first child of the log.
      //Perhaps we need to preprocess the log if this is the first condition to be met.
      if (!bMonitorFirst)
        throw new WSIException(
          "The Element \""
            + WSIConstants.ELEM_MONITOR
            + "\" is not the first child of the Element \"log\"");
    }
    catch (Exception e)
    {
      throw new WSIException(
        "An error occurred while processing the message log file.",
        e);
    }
  }

  /**
   * @see org.eclipse.wst.wsi.internal.core.document.DocumentReader#getLocation()
   */
  public String getLocation()
  {
    return this.documentURI;
  }

  /**
   * @see org.eclipse.wst.wsi.internal.core.document.DocumentReader#setLocation(String)
   */
  public void setLocation(String documentURI)
  {
    this.documentURI = documentURI;
  }

  /**
  * Process and handles elements and attribute in the log file and invokes
  * message validation assertions serially as the file is being processed,
  * if a messagevalidator exists.
  */
  private class LogFileHandler extends DefaultHandler
  {

    /** private members that represent a MessageEntry.*/
    private String id;
    private String conversationID;
    private String type;
    private String timestamp;
    private StringBuffer senderHostAndPort = null;
    private StringBuffer receiverHostAndPort  = null;
    private StringBuffer messageContent  = null;
    private StringBuffer httpHeaders  = null;
    private StringBuffer boundary  = null;
    private StringBuffer mimeHeaders = null;
    private StringBuffer mimeContent = null;
    private MimeParts mimeParts = null;
    private List boundaries = null;

    private int bom = 0;

    private String logTimestamp = null;
    private StringBuffer monitorComment;
    private boolean ignoreComment = false;

    /** Other private members */
    private String currentElement;

    private ElementLocation entryElementLocation = null;

    private ToolInfo toolInfo = null;

    private Vector messageEntryList = new Vector();

    private MessageEntryHandler logEntryHandler = null;

    private Locator locator = null;

    /**
     * Log file handler. 
     */
    public LogFileHandler(MessageEntryHandler logEntryHandler)
    {
      this.logEntryHandler = logEntryHandler;

      toolInfo = new ToolInfo();
      toolInfo.setToolEnvironment(new ToolEnvironment());
    }

    /** 
     * Start document. 
     */
    public void startDocument()
    {
    }

    /** 
     * Set document locato.
     */
    public void setDocumentLocator(Locator locator)
    {
      this.locator = locator;

      // DEBUG:
      //System.out.println("line: " + locator.getLineNumber() + ", column: " + locator.getColumnNumber());
    }

    /** 
     * Start element. 
     */
    public void startElement(
      String namespaceURI,
      String localName,
      String qName,
      Attributes attributes)
    {
      // DEBUG:
      //System.out.println("localName:" + localName + ", line: " + locator.getLineNumber() + ", column: " + locator.getColumnNumber());

      //Requirement, the implementer MUST be the first child of the log       
      if (elementCount == 2)
        if (firstLogElement == 1)
          bMonitorFirst = true;

      elementCount++;

      // <log>
      if (localName == WSIConstants.ELEM_LOG)
      {
        // Save the timestamp value
        this.logTimestamp = attributes.getValue(WSIConstants.ATTR_TIMESTAMP);
      }

      // <wsi-config:configuration>
      else if (
        (localName == WSIConstants.ELEM_CONFIG)
          && (namespaceURI == WSIConstants.NS_URI_WSI_MONITOR_CONFIG))
      {
        // Save comment element if it exists
        ignoreComment = false;
      }

      // <wsi-config:comment>
      else if (
        (localName == WSIConstants.ELEM_COMMENT)
          && (namespaceURI == WSIConstants.NS_URI_WSI_MONITOR_CONFIG))
      {
        // If this is the comment element within the configuration element, then get its content
        if (!ignoreComment)
        {
          currentElement = WSIConstants.ELEM_COMMENT;
          monitorComment = new StringBuffer();
        }
      }

      // <wsi-config:redirect>
      else if (
        (localName == WSIConstants.ELEM_REDIRECT)
          && (namespaceURI == WSIConstants.NS_URI_WSI_MONITOR_CONFIG))
      {
        // After hitting the first redirect statement, ignore all comment elements
        ignoreComment = true;
        monitorComment = null;
      }

      // <monitor>
      else if (localName == WSIConstants.ELEM_MONITOR)
      {
        firstLogElement++;
        toolInfo.setName(WSIConstants.ELEM_MONITOR);

        // Get the monitor version and release date
        toolInfo.setVersion(attributes.getValue(WSIConstants.ATTR_VERSION));
        toolInfo.setReleaseDate(
          attributes.getValue(WSIConstants.ATTR_RELEASE_DATE));
      }

      // <implementer>
      else if (localName == WSIConstants.ELEM_IMPLEMENTER)
      {
        currentElement = WSIConstants.ELEM_IMPLEMENTER;
        toolInfo.setImplementer(attributes.getValue(WSIConstants.ATTR_NAME));
        toolInfo.setLocation(attributes.getValue(WSIConstants.ATTR_LOCATION));
      }

      // <runtime>
      else if (localName == WSIConstants.ELEM_RUNTIME)
      {
        currentElement = WSIConstants.ELEM_RUNTIME;
        toolInfo.getToolEnvironment().setRuntimeName(
          attributes.getValue(WSIConstants.ATTR_NAME));
        toolInfo.getToolEnvironment().setRuntimeVersion(
          attributes.getValue(WSIConstants.ATTR_VERSION));
      }

      // <operatingSystem>
      else if (localName == WSIConstants.ELEM_OPERATING_SYSTEM)
      {
        currentElement = WSIConstants.ELEM_OPERATING_SYSTEM;
        toolInfo.getToolEnvironment().setOSName(
          attributes.getValue(WSIConstants.ATTR_NAME));
        toolInfo.getToolEnvironment().setOSVersion(
          attributes.getValue(WSIConstants.ATTR_VERSION));
      }

      // <xmlParser>
      else if (localName == WSIConstants.ELEM_XML_PARSER)
      {
        currentElement = WSIConstants.ELEM_XML_PARSER;
        toolInfo.getToolEnvironment().setXMLParserName(
          attributes.getValue(WSIConstants.ATTR_NAME));
        toolInfo.getToolEnvironment().setXMLParserVersion(
          attributes.getValue(WSIConstants.ATTR_VERSION));
      }

      // <messageEntry>
      else if (localName == WSIConstants.ELEM_MESSAGE_ENTRY)
      {
        currentElement = WSIConstants.ELEM_MESSAGE_ENTRY;
        entryElementLocation = new ElementLocation(this.locator);
        timestamp = attributes.getValue(WSIConstants.ATTR_TIMESTAMP);
        conversationID = attributes.getValue(WSIConstants.ATTR_CONVERSATION_ID);
        id = attributes.getValue(WSIConstants.ATTR_ID_UC);
        type = attributes.getValue(WSIConstants.ATTR_TYPE);
      }

      // <httpHeaders>
      else if (localName == WSIConstants.ELEM_HTTP_HEADERS)
      {
        //Note: Character data could be split up and returned 
        //in more more than one characters call. 
        httpHeaders = new StringBuffer();
        currentElement = WSIConstants.ELEM_HTTP_HEADERS;
      }

      // <messageContent>
      else if (localName == WSIConstants.ELEM_MESSAGE_CONTENT)
      {
        messageContent = new StringBuffer();
        mimeParts = null;
        currentElement = WSIConstants.ELEM_MESSAGE_CONTENT;
        String bomString = attributes.getValue(WSIConstants.ATTR_BOM);
        if (bomString != null)
          bom = Integer.valueOf(bomString).intValue();
        else
          bom = 0;
      }

      // <messageContentWithAttachments>
      else if (localName == WSIConstants.ELEM_MESSAGE_CONTENT_WITH_ATTACHMENTS)
      {
        messageContent = null;
        mimeParts = new MimePartsImpl();

        String bomString = attributes.getValue(WSIConstants.ATTR_BOM);
        if (bomString != null)
          bom = Integer.valueOf(bomString).intValue();
        else
          bom = 0;
      }

      // <mimePart>
      else if (localName == WSIConstants.ELEM_MIME_PART)
      {
        if (boundaries == null)
          boundaries = new ArrayList(2);
        else
          boundaries.clear();
      }

      // <boundaryString>
      else if (localName == WSIConstants.ELEM_BOUNDARY_STRING)
      {
        boundary = new StringBuffer();
        currentElement = WSIConstants.ELEM_BOUNDARY_STRING;
      }

      // <mimeHeaders>
      else if (localName == WSIConstants.ELEM_MIME_HEADERS)
      {
        mimeHeaders = new StringBuffer();
        currentElement = WSIConstants.ELEM_MIME_HEADERS;
      }

      // <mimeContent>
      else if (localName == WSIConstants.ELEM_MIME_CONTENT)
      {
        mimeContent = new StringBuffer();
        currentElement = WSIConstants.ELEM_MIME_CONTENT;
      }

      // <senderHostAndPort>
      else if (localName == WSIConstants.ELEM_SENDER_HOST_AND_PORT)
      {
        senderHostAndPort = new StringBuffer();
        currentElement = WSIConstants.ELEM_SENDER_HOST_AND_PORT;
      }

      // <receiverHostAndPort>
      else if (localName == WSIConstants.ELEM_RECEIVER_HOST_AND_PORT)
      {
        receiverHostAndPort = new StringBuffer();
        currentElement = WSIConstants.ELEM_RECEIVER_HOST_AND_PORT;
      }
    }

    /** 
    * Characters callback. 
    */
    public void characters(char ch[], int start, int length)
    {
      // Ignoring CRLF that appears in log elements
      int altStart = start;
      int altLength = length;
      if (start > 0 && ch[start-1] == 13 && ch[start] == 10)
      {
        altStart++;
        altLength--;
      }

      // <wsi-monConfig:comment>
      if (monitorComment != null && currentElement == WSIConstants.ELEM_COMMENT)
      {
        monitorComment.append(ch, start, length);
      }

      // <messageContent>
      else if (messageContent != null
        && currentElement == WSIConstants.ELEM_MESSAGE_CONTENT)
      {
        messageContent.append(ch, start, length);
      }

      // <httpHeaders>
      else if (httpHeaders != null
        && currentElement == WSIConstants.ELEM_HTTP_HEADERS)
      {
        httpHeaders.append(ch, start, length);
      }

      // <boundaryString>
      else if (boundary != null
        && currentElement == WSIConstants.ELEM_BOUNDARY_STRING)
      {
        boundary.append(ch, altStart, altLength);
      }

      // <mimeHeaders>
      else if (mimeHeaders != null
        && currentElement == WSIConstants.ELEM_MIME_HEADERS)
      {
        mimeHeaders.append(ch, altStart, altLength);
      }

      // <mimeContent>
      else if (mimeContent != null
        && currentElement == WSIConstants.ELEM_MIME_CONTENT)
      {
        mimeContent.append(ch, altStart, altLength);
      }

      // <senderHostAndPort>
      else if (senderHostAndPort != null
        && currentElement == WSIConstants.ELEM_SENDER_HOST_AND_PORT)
      {
        senderHostAndPort.append(ch, start, length);
      }

      // <receiverHostAndPort>
      else if (receiverHostAndPort != null
        && currentElement == WSIConstants.ELEM_RECEIVER_HOST_AND_PORT)
      {
        receiverHostAndPort.append(ch, start, length);
      }
    }

    /** 
     * End Element. 
     */
    public void endElement(String namespaceURI, String localName, String qName)
    {
      // <wsi-config:comment>
      if (
        (localName == WSIConstants.ELEM_COMMENT)
          && (namespaceURI == WSIConstants.NS_URI_WSI_MONITOR_CONFIG))
      {
        // If we saved the comment, then process it and the log timestamp
        if (this.monitorComment != null)
        {
          ArtifactReference artifactReference = new ArtifactReferenceImpl();
          artifactReference.setTimestamp(this.logTimestamp);
          Comment comment = new CommentImpl();
          comment.setText(monitorComment.toString());
          artifactReference.setDocumentElement(
            comment,
            WSIConstants.NS_NAME_WSI_MONITOR_CONFIG);
          processArtifactReference(artifactReference);
        }
      }

      // <boundaryString>
      else if (localName == WSIConstants.ELEM_BOUNDARY_STRING)
      {
        // Adding boundary string to a list
        boundaries.add(boundary.toString());
      }

      // <mimePart>
      else if (localName == WSIConstants.ELEM_MIME_PART)
      {
        // Creating a MessageMIMEPart instance
        MimePart part = new MimePartImpl();
        part.setHeaders(mimeHeaders.toString());
        part.setContent(mimeContent.toString());
        part.setBoundaryStrings((String[])boundaries.toArray(new String[0]));

        mimeParts.addPart(part);
      }

      // <messageEntry>
      else if (localName == WSIConstants.ELEM_MESSAGE_ENTRY)
      {
        // Assumption: Related messages are sequentially available in the message log.
        if (MessageEntry.TYPE_REQUEST.equalsIgnoreCase(type))
        {
          // Create log entry
          MessageEntry messageEntryRequest =
            createMessageEntry(
                id,
                conversationID,
                type,
                timestamp,
                senderHostAndPort.toString(),
                receiverHostAndPort.toString(),
                messageContent == null ? "" : messageContent.toString(),
                httpHeaders.toString(),
                mimeParts,
                entryElementLocation);

          // Add log entry to the list
          messageEntryList.add(messageEntryRequest);

          // Request is now processed only when the response is received.             
        }

        else if (MessageEntry.TYPE_RESPONSE.equalsIgnoreCase(type))
        {
          // Create log entry
          MessageEntry messageEntryResponse =
            createMessageEntry(
                id,
                conversationID,
                type,
                timestamp,
                senderHostAndPort.toString(),
                receiverHostAndPort.toString(),
                messageContent == null ? "" : messageContent.toString(),
                httpHeaders.toString(),
                mimeParts,
                entryElementLocation);

          // Add log entry to the list
          messageEntryList.add(messageEntryResponse);

          if (logEntryHandler != null)
          {
            // look up the request message
            // ISSUE : need to throw & catch a nullpointerexception in here...
            MessageEntry messageEntryRequest = findRelatedRequest(messageEntryResponse);

            if (messageEntryRequest != null)
            {
              // Create entry 
              // ADD: Need to create entry from report
              //Entry entry = this.reporter.getReport().createEntry();
              Entry entry = new EntryImpl();
              entry.setEntryType(
                  EntryType.getEntryType(EntryType.TYPE_MESSAGE_REQUEST));
              entry.setReferenceID(messageEntryRequest.getId());
              entry.setEntryDetail(messageEntryRequest);

              // Create the context for the request-response pair
              EntryContext requestTargetContext =
                new EntryContext(
                    entry,
                    messageEntryRequest,
                    messageEntryResponse);
              if (requestTargetContext != null)
                processLogEntry(requestTargetContext);
            }

            // Create entry 
            // ADD: Need to create entry from report
            //Entry entry = this.reporter.getReport().createEntry();
            Entry entry = new EntryImpl();
            entry.setEntryType(
                EntryType.getEntryType(EntryType.TYPE_MESSAGE_RESPONSE));
            entry.setReferenceID(messageEntryResponse.getId());
            entry.setEntryDetail(messageEntryResponse);

            EntryContext responseTargetContext =
              new EntryContext(
                  entry,
                  messageEntryRequest,
                  messageEntryResponse);
            if (responseTargetContext != null)
              processLogEntry(responseTargetContext);
          }
        }
      }

      currentElement = null;
    }

    /** 
    * End Document. 
    */
    public void endDocument()
    {
      //If we want to serially process the log file.  Invoke validateMessages with
      //msgValidator!=null.  Here we have the option of clearing the logEntry vector
      //once message validation is done.
      //if (msgValidator!=null)
      //logEntryList.clear();
    }

    /**
     * Process the message in the log entry.
     */
    public void processLogEntry(EntryContext entryContext)
    {
      try
      {
        //Before validating any messages check if implementer is the first element.
        logEntryHandler.processLogEntry(entryContext);
      }
      catch (Exception e)
      {
        wsiException =
          new WSIException(
            "An error occurred while validating"
              + " the message logEntry: "
              + entryContext.getMessageEntry().getId(),
            e);
      }
    }

    /**
     * Process the artifact reference.
     */
    private void processArtifactReference(ArtifactReference artifactReference)
    {
      try
      {
        //Before validating any messages check if implementer is the first element.
        logEntryHandler.processArtifactReference(artifactReference);
      }

      catch (Exception e)
      {
        wsiException =
          new WSIException(
            "An error occurred while processing"
              + " the artifact reference: "
              + artifactReference.toString(),
            e);
      }
    }

    /**
       * Find the related Request LogEntry.  The current rule for related log entires is
       * that a request will always precede its response.
       * ISSUE: Sequence in log file is timestamp driven (monitor spec). 
       * Assertion is that for a given conversationID, a second request is not sent 
       * until its response is received (chronologically). 
       * This method will have to be modified if the rule changes.
       */
    // could be made more efficient by keeping a much smaller list of unresponded requests...
    public MessageEntry findRelatedRequest(MessageEntry logEntryResponse)
    {
      for (int entry = messageEntryList.size() - 1; entry >= 0; entry--)
      {
        // Get the log entry of the matching request
        MessageEntry logEntry = (MessageEntry) messageEntryList.get(entry);
        // Ignore own entry
        if (!logEntryResponse.equals(logEntry))
        {
          if (logEntryResponse
            .getConversationId()
            .equals(logEntry.getConversationId()))
          {
            // found the most recently read message with the same conversationID.
            // From above, this should be the corresponding request. Check as far as possible.
            if (logEntry.getType().equals(MessageEntry.TYPE_REQUEST))
            {
              return logEntry;
            }
            else
            {
              return null; // expected a request. need to throw an exception!
            }
          }
        }
      }
      return null;
      // conversationID match not found anywhere. need to throw an exception!
    }

    /**
     * Create log entry.
     */
    private MessageEntry createMessageEntry(
      String id,
      String conversationId,
      String type,
      String timestamp,
      String senderIPPort,
      String receiverIPPort,
      String messageContent,
      String httpHeaders,
      MimeParts mimeParts,
      ElementLocation elementLocation)
    {
      // Create log entry
      MessageEntry messageEntry = new MessageEntryImpl();
      messageEntry.setId(id);
      messageEntry.setConversationId(conversationID);
      messageEntry.setType(type);
      messageEntry.setTimestamp(timestamp);
      messageEntry.setSenderHostAndPort(senderIPPort);
      messageEntry.setReceiverHostAndPort(receiverIPPort);
      messageEntry.setHTTPHeaders(httpHeaders);
      messageEntry.setBOM(bom);
      messageEntry.setElementLocation(elementLocation);

      String encoding = null;
      if (mimeParts == null)
      {
        // Get the encoding for this message content
        encoding = Utils.getXMLEncoding(messageContent);
        messageEntry.setMessage(messageContent);
       	messageEntry.setMimeContent(false);
      }
      else
      {
       	messageEntry.setMimeParts(mimeParts);
       	MimePart root = Utils.findRootPart(httpHeaders, mimeParts.getParts());
       	if (root != null)
       	{
          // Get the encoding for this message content
          encoding = Utils.getXMLEncoding(root.getContent());
          mimeParts.setRootPart(root);
       	}
   		// else empty body
       	messageEntry.setMimeContent(true);
      }
      if ((encoding == null) || (encoding.equals("")))
         encoding = WSIConstants.DEFAULT_XML_ENCODING;
      messageEntry.setEncoding(encoding);

      return messageEntry;
    }

  } //End ContentHandler
}