/*******************************************************************************
 * Copyright (c) 2002-2003 IBM Corporation, Parasoft, 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
 *   Parasoft - Initial API and implementation
 *   BeaconIT - Initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.wsi.internal.core.analyzer;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;

import javax.wsdl.WSDLException;

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.WSIFileNotFoundException;
import org.eclipse.wst.wsi.internal.core.log.LogReader;
import org.eclipse.wst.wsi.internal.core.log.MessageEntryHandler;
import org.eclipse.wst.wsi.internal.core.profile.ProfileAssertionsReader;
import org.eclipse.wst.wsi.internal.core.profile.validator.EntryContext;
import org.eclipse.wst.wsi.internal.core.profile.validator.EnvelopeValidator;
import org.eclipse.wst.wsi.internal.core.profile.validator.MessageValidator;
import org.eclipse.wst.wsi.internal.core.profile.validator.UDDIValidator;
import org.eclipse.wst.wsi.internal.core.profile.validator.WSDLValidator;
import org.eclipse.wst.wsi.internal.core.report.ArtifactReference;
import org.eclipse.wst.wsi.internal.core.report.AssertionResult;
import org.eclipse.wst.wsi.internal.core.report.Report;
import org.eclipse.wst.wsi.internal.core.report.ReportArtifact;
import org.eclipse.wst.wsi.internal.core.report.ReportContext;
import org.eclipse.wst.wsi.internal.core.report.ReportWriter;
import org.eclipse.wst.wsi.internal.core.report.impl.DefaultReporter;
import org.eclipse.wst.wsi.internal.core.util.ArtifactType;
import org.eclipse.wst.wsi.internal.core.util.WSIProperties;
import org.eclipse.wst.wsi.internal.core.wsdl.WSDLDocument;
import org.eclipse.wst.wsi.internal.core.xml.XMLDocumentCache;
import org.uddi4j.transport.TransportFactory;


/**
 * Analyzes log files to confirm conformance to a profile.
 *
 * @version 1.0.1
 * @author Jim Clune
 * @author Peter Brittenham
 * @author Graham Turrell
 */
public class BasicProfileAnalyzer extends Analyzer
{
  /**
   * Tool information.
   */
  public static final String TOOL_NAME = "Analyzer";

  /**
   * WSDL document to analyze.
   */
  protected WSDLDocument wsdlDocument = null;

  /**
   * Basic profile analyzer.
   * @param args command line arguments.
   * @throws WSIException if unable to create a Basic profile analyzer.
   */
  public BasicProfileAnalyzer(String[] args) throws WSIException
  {
    super(args, new ToolInfo(TOOL_NAME));
    new XMLDocumentCache();
  }

  /**
   * Basic profile analyzer.
   * @param args command line arguments.
   * @param validate flag for command line argument validation.
   * @throws WSIException if unable to create a Basic profile analyzer.
   */
  public BasicProfileAnalyzer(String[] args, boolean validate) throws WSIException
  {
    super(args, new ToolInfo(TOOL_NAME), validate);
    new XMLDocumentCache();
  }

  /**
   * Basic profile analyzer.
   * @param analyzerConfigList a list of configurations for the analyzer.
   * @throws WSIException if unable to create a Basic profile analyzer.
   */
  public BasicProfileAnalyzer(List analyzerConfigList) throws WSIException
  {
    super(analyzerConfigList, new ToolInfo(TOOL_NAME));
    new XMLDocumentCache();
  }

  /**
   * Basic profile analyzer.
   * @param analyzerConfigList a list of configurations for the analyzer.
   * @param wsdlURI a wsdl document location.
   * @throws WSIException if unable to create a Basic profile analyzer.
   */
  public BasicProfileAnalyzer(List analyzerConfigList, String wsdlURI)
    throws WSIException
  {
    super(analyzerConfigList, new ToolInfo(TOOL_NAME));
    new XMLDocumentCache();
    
    try
    {
      // Get the WSDL document
      if (wsdlURI != null)
        this.wsdlDocument = new WSDLDocument(wsdlURI);
    }

    catch (WSDLException we)
    {
      throw new WSIException(we.getMessage(), we);
    }

  }

  /**
   * Process all conformance validation functions.
   * @return status code.
   * @throws WSIException if conformance validation process failed.
   */
  public int validateConformance() throws WSIException
  {
    int statusCode = 0;

    Report report = null;
    ReportArtifact reportArtifact = null;
    String wsdlURI = null;
    //WSDLDocument wsdlDocument = null;

    // Set up initial analyzer context based on entries in the config file
    this.analyzerContext =
      new AnalyzerContext(new ServiceReference(getAnalyzerConfig()));

    try
    {
      // Read profile assertions
      ProfileAssertionsReader profileAssertionsReader =
        documentFactory.newProfileAssertionsReader();
      this.profileAssertions =
        profileAssertionsReader.readProfileAssertions(
          getAnalyzerConfig().getTestAssertionsDocumentLocation());

      // Create report from document factory
      report = documentFactory.newReport();
      report.setLocation(getAnalyzerConfig().getReportLocation());

      // Create report context
      ReportContext reportContext =
        new ReportContext(
          WSIConstants.DEFAULT_REPORT_TITLE,
          profileAssertions,
          this);
      report.setReportContext(reportContext);

      // Create report writer
      ReportWriter reportWriter = documentFactory.newReportWriter();
      // I18N: 2003.02.26 modified by K.Nakagome@BeaconIT 
      //reportWriter.setWriter(new FileWriter(analyzerConfig.getReportLocation()));
      reportWriter.setWriter(getAnalyzerConfig().getReportLocation());

      // Create reporter
      this.reporter = new DefaultReporter(report, reportWriter);

      // Start writing report
      this.reporter.startReport();

      // --------------------------------
      // DISCOVERY ARTIFACT:
      // --------------------------------

      // Set current artifact
      reportArtifact = setCurrentArtifact(ArtifactType.ARTIFACT_TYPE_DISCOVERY);

      // If UDDI options specified, then process UDDI test assertions
      if ((wsdlURI = validateUDDI(reportArtifact, factory.newUDDIValidator()))
        == null)
      {
        if (getAnalyzerConfig().isWSDLReferenceSet())
        {
          // Otherwise use the WSDL options to get the WSDL location
          wsdlURI = getAnalyzerConfig().getWSDLLocation();
        }
      }

      // Indicate that we are done with this artifact
      this.reporter.endCurrentArtifact();

      // --------------------------------
      // DESCRIPTION ARTIFACT:
      // --------------------------------

      // Set current artifact
      reportArtifact =
        setCurrentArtifact(ArtifactType.ARTIFACT_TYPE_DESCRIPTION);

      // Call WSDLValidator 
      wsdlDocument =
        validateWSDL(
          reportArtifact,
          factory.newWSDLValidator(),
          wsdlURI,
          wsdlDocument);

      // If WSDL document object is null, then throw exception
      if ((wsdlDocument == null) && (getAnalyzerConfig().isWSDLReferenceSet()))
      {
        throw new WSIException(
          messageList.getMessage(
            "config05",
            "WSDL document was either not found or could not be processed."));
      }

      // Indicate that we are done with this artifact
      this.reporter.endCurrentArtifact();

      // REMOVE:
      // If processing log entries and there isn't a WSDL URI, 
      // then throw an exception since it is required to process the log entries
      //if ((wsdlURI == null) && (analyzerConfig.getLogLocation() != null)) {
      //  throw new WSIException("Must specify the WSDL document location to validate message log.");
      //}

      // --------------------------------
      // MESSAGE ARTIFACT:
      // --------------------------------

      // Set current artifact
      reportArtifact = setCurrentArtifact(ArtifactType.ARTIFACT_TYPE_MESSAGE);

      // Process test assertions for the messages
      validateMessages(
        reportArtifact,
        factory.newMessageValidator(),
        wsdlDocument);

      // Indicate that we are done with this artifact
      this.reporter.endCurrentArtifact();

      // --------------------------------
      // ENVELOPE ARTIFACT:
      // --------------------------------

      // If that is not the Basic Profile 1.0, then process
      // the envelope artifact
      if (!profileAssertions.getTADName()
        .equals(WSIConstants.BASIC_PROFILE_TAD_NAME))
      {

        // Set current artifact
        reportArtifact = setCurrentArtifact(ArtifactType.ARTIFACT_TYPE_ENVELOPE);

        // Process test assertions for the envelopes
        validateEnvelopes(
          reportArtifact,
          factory.newEnvelopeValidator(),
          wsdlDocument);

        // Indicate that we are done with this artifact
        this.reporter.endCurrentArtifact();
      }

      // Finish the conformance report
      reporter.finishReport();
    }

    catch (Exception e)
    {
      StringWriter sw = new StringWriter();
      PrintWriter pw = new PrintWriter(sw);

      String message =
        messageList.getMessage(
          "error03",
          "The conformance validation process failed.");

      // Finish report
      if (reporter != null)
      {
        pw.println(message);
        pw.println(
          messageList.getMessage("exception01", "Exception: ")
            + e.getClass().getName());
        e.printStackTrace(pw);
        reporter.finishReportWithError(sw.toString());
      }

      if (e instanceof WSIException)
        throw (WSIException) e;
      else
        throw new WSIException(message, e);
    }

    if (report != null)
    {
      statusCode =
        (report.getSummaryResult().equals(AssertionResult.RESULT_PASSED)
          ? 0
          : 1);
    }

    return statusCode;
  }

  /**
   * Run UDDI test assertions.
   */
  private String validateUDDI(
    ReportArtifact reportArtifact,
    UDDIValidator uddiValidator)
    throws WSIException
  {
    String wsdlURI = null;

    // Init UDDIValidator
    uddiValidator.init(
      this.analyzerContext,
      this.profileAssertions.getArtifact(ArtifactType.TYPE_DISCOVERY),
      reportArtifact,
      getAnalyzerConfig().getUDDIReference(),
      this.reporter);

    // Call UDDIValidator 
    if (getAnalyzerConfig().isUDDIReferenceSet())
    {
      wsdlURI = uddiValidator.validate();

      // Cleanup
      uddiValidator.cleanup();
    }

    else
    {
      // Set all missingInput
      uddiValidator.setAllMissingInput();
    }

    return wsdlURI;
  }

  /**
   * Run WSDL test assertions.
   */
  private WSDLDocument validateWSDL(
    ReportArtifact reportArtifact,
    WSDLValidator wsdlValidator,
    String wsdlURI,
    WSDLDocument wsdlDocument)
    throws WSIException
  {
    WSDLDocument returnWSDLDocument = null;

    // Init WSDLValidator
    wsdlValidator.init(
      this.analyzerContext,
      this.profileAssertions.getArtifact(ArtifactType.TYPE_DESCRIPTION),
      reportArtifact,
      wsdlURI,
      wsdlDocument,
      this.reporter);

    // If a WSDL URI was specified or located in a UDDI registry, then process the WSDL tests
    if (wsdlURI != null || wsdlDocument != null)
    {
      // Call WSDLValidator 
      returnWSDLDocument = wsdlValidator.validate();

      // Cleanup
      wsdlValidator.cleanup();
    }

    else
    {
      // Set all missingInput
      wsdlValidator.setAllMissingInput();
    }

    return returnWSDLDocument;
  }

  /**
   * Run message test assertions.
   */
  private void validateMessages(
    ReportArtifact reportArtifact,
    MessageValidator messageValidator,
    WSDLDocument wsdlDocument)
    throws WSIException
  {
    //Log log = null;
    //MessageEntry logEntry = null;

    // Init MessageValidator
    messageValidator.init(
      this.analyzerContext,
      this.profileAssertions.getArtifact(ArtifactType.TYPE_MESSAGE),
      reportArtifact,
      wsdlDocument,
      this.reporter);

    // If the log file location was specified, then process test assertions for the messages
    if (getAnalyzerConfig().getLogLocation() != null)
    {
      // Get the log file reader
      LogReader logReader = documentFactory.newLogReader();

      // Create log reader callback
      MessageProcessor messageProcessor =
        new MessageProcessor(messageValidator);

      // Start reading the log file
      logReader.readLog(getAnalyzerConfig().getLogLocation(), messageProcessor);

      // Cleanup
      messageValidator.cleanup();
    }

    // Otherwise all are missingInput
    else
    {
      // Set all missingInput
      messageValidator.setAllMissingInput();
    }
  }

  /**
   * Run envelope test assertions.
   */
  private void validateEnvelopes(
    ReportArtifact reportArtifact,
    EnvelopeValidator envelopeValidator,
    WSDLDocument wsdlDocument)
    throws WSIException
  {
    // Init envelopeValidator
    envelopeValidator.init(
      this.analyzerContext,
      this.profileAssertions.getArtifact(ArtifactType.TYPE_ENVELOPE),
      reportArtifact,
      wsdlDocument,
      this.reporter);

    // If the log file location was specified, then process test assertions for the messages
    if (getAnalyzerConfig().getLogLocation() != null)
    {
      // Get the log file reader
      LogReader logReader = documentFactory.newLogReader();

      // Create log reader callback
      EnvelopeProcessor envelopeProcessor =
        new EnvelopeProcessor(envelopeValidator);

      // Start reading the log file
      logReader.readLog(getAnalyzerConfig().getLogLocation(), envelopeProcessor);

      // Cleanup
      envelopeValidator.cleanup();
    }

    // Otherwise all are missingInput
    else
    {
      // Set all missingInput
      envelopeValidator.setAllMissingInput();
    }
  }

  /**
   * Command line interface for the analyzer tool.
   * @param args command line arguments.
   * @throws IOException if IO problems occur.
   */
  public static void main(String[] args) throws IOException
  {
    int statusCode = 0;
    Analyzer analyzer = null;

    try
    {
      // Set document builder factory class
      System.setProperty(
        WSIProperties.PROP_JAXP_DOCUMENT_FACTORY,
        WSIProperties.getProperty(WSIProperties.PROP_JAXP_DOCUMENT_FACTORY));

      // Set the system property for UDDI4J transport
      System.setProperty(
        TransportFactory.PROPERTY_NAME,
        WSIProperties.getProperty(TransportFactory.PROPERTY_NAME));

      // Create the analyzer object
      analyzer = new BasicProfileAnalyzer(args);

      // Have it process the conformance validation functions
      statusCode = analyzer.validateConformance();

      // Display message
      analyzer.printMessage(
        "created01",
        null,
        "Conformance report has been created.");
    }

    catch (Exception e)
    {
      statusCode = 1;

      boolean printStackTrace = true;
      String messageID;
      String defaultMessage;
      String messageData;

      if ((e instanceof WSIFileNotFoundException)
        || (e instanceof IllegalArgumentException))
      {
        //printStackTrace = false;
        messageID = "error01";
        defaultMessage = "Analyzer Error:";
        messageData = e.getMessage();
      }

      else
      {
        //printStackTrace = true;
        messageID = "error02";
        defaultMessage = "Analyzer Stopped By Exception:";
        messageData = e.toString();
      }

      if (analyzer != null)
        analyzer.printMessage(messageID, messageData, defaultMessage);
      else
        Analyzer.staticPrintMessage(messageID, messageData, defaultMessage);

      if (analyzer != null
        && analyzer.getAnalyzerConfig() != null
        && analyzer.getAnalyzerConfig().getVerboseOption())
        dump(e);
    }

    // Exit
    System.exit(statusCode);
  }

  /**
   * Set current artifact.
   * @param artifactType an ArtifactType object.
   * @return a ReportArtifact object.
   * @throws WSIException if problems creating report artifact.
   */
  protected ReportArtifact setCurrentArtifact(ArtifactType artifactType)
    throws WSIException
  {
    // Create artifact
    ReportArtifact reportArtifact = reporter.createArtifact();
    reportArtifact.setType(artifactType);

    // Add artifact to report
    this.reporter.setCurrentArtifact(reportArtifact);

    return reportArtifact;
  }

  /**
   * Print exception.
   * @param t a Throwable object.
   */
  public static void dump(Throwable t)
  {
    while (t instanceof WSIException)
    {
      Throwable nested = ((WSIException) t).getTargetException();
      if (nested == null)
        break;
      else
        t = nested;
    }
    t.printStackTrace();
  }

  /**
   * Message processor class.
   */
  class MessageProcessor implements MessageEntryHandler
  {
    MessageValidator messageValidator = null;

    /**
     * Create message processor as a log reader callback function.
     */
    MessageProcessor(MessageValidator messageValidator)
    {
      this.messageValidator = messageValidator;
    }

    /**
     * Process artifact reference.
     */
    public void processArtifactReference(ArtifactReference artifactReference)
      throws WSIException
    {
      reporter.addArtifactReference(artifactReference);
    }

    /**
     * Process a single log entry.
     */
    public void processLogEntry(EntryContext entryContext) throws WSIException
    {
      // Validate message
      messageValidator.validate(entryContext);
    }

  }

  /**
   * Envelope processor class.
   */
  class EnvelopeProcessor implements MessageEntryHandler
  {
    EnvelopeValidator envelopeValidator = null;

    /**
     * Create envelope processor as a log reader callback function.
     */
    EnvelopeProcessor(EnvelopeValidator envelopeValidator)
    {
      this.envelopeValidator = envelopeValidator;
    }

    /**
     * Process artifact reference.
     */
    public void processArtifactReference(ArtifactReference artifactReference)
      throws WSIException
    {
      reporter.addArtifactReference(artifactReference);
    }

    /**
     * Process a single log entry.
     */
    public void processLogEntry(EntryContext entryContext) throws WSIException
    {
      // Validate envelopes
      envelopeValidator.validate(entryContext);
    }

  }
}
