/*******************************************************************************
 * 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.profile.validator.impl;

import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.TreeMap;
import java.util.Vector;

import org.eclipse.wst.wsi.internal.core.WSIException;
import org.eclipse.wst.wsi.internal.core.analyzer.AnalyzerContext;
import org.eclipse.wst.wsi.internal.core.profile.ProfileArtifact;
import org.eclipse.wst.wsi.internal.core.profile.TestAssertion;
import org.eclipse.wst.wsi.internal.core.profile.validator.BaseValidator;
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.report.AssertionResult;
import org.eclipse.wst.wsi.internal.core.report.Entry;
import org.eclipse.wst.wsi.internal.core.report.FailureDetail;
import org.eclipse.wst.wsi.internal.core.report.PrereqFailedList;
import org.eclipse.wst.wsi.internal.core.report.ReportArtifact;
import org.eclipse.wst.wsi.internal.core.report.Reporter;
import org.eclipse.wst.wsi.internal.core.report.impl.PrereqFailedListImpl;
import org.eclipse.wst.wsi.internal.core.util.EntryType;
import org.eclipse.wst.wsi.internal.core.xml.XMLDocumentCacheUser;
import org.eclipse.wst.wsi.internal.core.xml.dom.ElementLocation;

/**
 * The WSDL validator will verify that the WSDL and associated XML schema definitions
 * are in conformance with the profile.
 *
 * @version 1.0.1
 * @author Peter Brittenham (peterbr@us.ibm.com)
 * @author Graham Turrell   (gturrell@uk.ibm.com)
 */
public abstract class BaseValidatorImpl
  extends XMLDocumentCacheUser
  implements BaseValidator
{

  /**
   * A hashtable that maps assertion results to their priorities, 0 is lowest
   */
  private static final Hashtable resultPriority = new Hashtable(6);
  static {
    resultPriority.put(AssertionResult.RESULT_PASSED, new Integer(0));
    resultPriority.put(AssertionResult.RESULT_NOT_APPLICABLE, new Integer(1));
    resultPriority.put(AssertionResult.RESULT_MISSING_INPUT, new Integer(2));
    resultPriority.put(AssertionResult.RESULT_WARNING, new Integer(3));
    resultPriority.put(AssertionResult.RESULT_PREREQ_FAILED, new Integer(4));
    resultPriority.put(AssertionResult.RESULT_FAILED, new Integer(5));
  }

  /**
   * The highest priority value being passed when processing pre-requisites
   */
  private static final int MAX_VALID_PRIORITY = 1;

  /**
   * Analyzer context.
   */
  public AnalyzerContext analyzerContext;

  /**
   * Profile artifact.
   */
  protected ProfileArtifact profileArtifact;

  /**
   * Reporter.
   */
  protected Reporter reporter;

  /**
   * Entry.
   */
  // protected Entry entry;

  /**
   * Report artifact.
   */
  protected ReportArtifact reportArtifact;

  /**
   * Verbose option.
   */
  public boolean verboseOption = false;

  /**
   * Test assertion processed count.
   */
  protected int assertionCount = 0;

  /**
   * Constructor.
   */
  public BaseValidatorImpl()
  {
  }

  /**
   * Initiailize validation test procedure.
   * @param analyzerContext the analyzerContext.
   * @param profileArtifact the profile artifiact.
   * @param reportArtifact  the report artifact.
   * @param reporter        a Reporter object.
   * @throws WSIException if validator could not be initialized.
   */
  public void init(
    AnalyzerContext analyzerContext,
    ProfileArtifact profileArtifact,
    ReportArtifact reportArtifact,
    Reporter reporter)
    throws WSIException
  {
    // Save input references
    this.analyzerContext = analyzerContext;
    this.profileArtifact = profileArtifact;
    this.reportArtifact = reportArtifact;
    this.reporter = reporter;

    // Make sure that the XML document cache is updated in the analyzer context
    this.documentList = this.analyzerContext.getDocumentList();

    // Get verbose option    
    verboseOption =
      reporter
        .getReport()
        .getReportContext()
        .getAnalyzer()
        .getAnalyzerConfig()
        .getVerboseOption();
  }

  /**
   * Process all of the test assertions for one entry.
   * @param classPrefix a class prefix.
   * @param entryContext an entry context.
   * @throws WSIException if serious problems occur while processing 
   *         all of the test assertions for an entry.
   */
  protected void processAssertions(
    String classPrefix,
    EntryContext entryContext)
    throws WSIException
  {
    long startTime = 0;

    HashMap processList = new HashMap();
    TestAssertion testAssertion = null;
    AssertionProcess assertionProcess;
    AssertionResult assertionResult;

    TreeMap preReqResults;
    PrereqFailedList prereqFailedList;
    String preReqId;

    Class[] paramTypes = new Class[1];
    // If this is an instance of MessageValidator or EnvelopeValidator
    // then use BaseMessageValidator as a param type of assertions constructor
    paramTypes[0] = this instanceof BaseMessageValidator ?
      BaseMessageValidator.class : this.getClass();

    Object[] params = new Object[1];
    params[0] = this;

    // Get entry from context
    Entry entry = entryContext.getEntry();

    // Add entry to artifact
    this.reportArtifact.addEntry(entry);

    // Add entry to report
    if (this instanceof EnvelopeValidator)
     	this.reporter.setCurrentEnvelopeEntry(entry); 
	else this.reporter.setCurrentEntry(entry);

    try
    {
      // Go through the list of test assertions for the artifact
      Iterator iterator = profileArtifact.getTestAssertionList().iterator();
      while (iterator.hasNext())
      {
        // Get next test assertion
        testAssertion = (TestAssertion) iterator.next();

        // Reset variables
        assertionResult = null;

        // If the test assertion is enabled, then continue
        //        if ((testAssertion.isEnabled()) && 
        //            testAssertion.getEntryTypeName().equals(targetContext.getEntry().getEntryType().getTypeName())) { 
        if (testAssertion.isEnabled()
          && isPrimaryEntryTypeMatch(testAssertion, entryContext))
        {
          try
          {
            // Add 1 to assertion processed count
            assertionCount++;

            // If the assertion process hasn't been created yet, then create it
            if ((assertionProcess =
              (AssertionProcess) processList.get(testAssertion.getId()))
              == null)
            {

              // Create a new assertion process
              Class assertionClass =
                Class.forName(classPrefix + testAssertion.getId());

              assertionProcess =
                (AssertionProcess) assertionClass.getConstructor(
                  paramTypes).newInstance(
                  params);

              // Add it to the list
              processList.put(testAssertion.getId(), assertionProcess);
            }

            // Check whether entry is null
            if (entry.getEntryDetail() == null)
            {
              assertionResult =
                createAssertionResult(
                  testAssertion,
                  AssertionResult.RESULT_MISSING_INPUT,
                  (String) null);
            }

            // Check to see if the test assertion should be run
            //if (isNotApplicable(testAssertion, entryContext)) {
            else if (isNotApplicable(testAssertion))
            {
              assertionResult =
                createAssertionResult(
                  testAssertion,
                  AssertionResult.RESULT_NOT_APPLICABLE,
                  (String) null);
            }
            else
            {
              // Processing all the assertion pre-requisites

              preReqResults = null;
              prereqFailedList = null;
              // Get list of pre-reqs for specified assertion
              Iterator i = testAssertion.getPrereqIdList().iterator();
              while (i.hasNext())
              {
                if (preReqResults == null)
                  preReqResults = new TreeMap();
                // Get next id
                preReqId = (String) i.next();
                // Get the prereq result
                AssertionResult preReqResult = reporter.getAssertionResult(preReqId);

                // Adding a result priority value to preReqResults
                preReqResults.put(
                  resultPriority.get(preReqResult.getResult()),
                  preReqResult.getResult());

                // If the prereq failed, then add it to the list
                if (((Integer)resultPriority.get(preReqResult.getResult())).intValue()
                  > MAX_VALID_PRIORITY)
                {
                  // Adding failed prereq ID to the list
                  if (prereqFailedList == null)
                    prereqFailedList = new PrereqFailedListImpl();
                  prereqFailedList.addTestAssertionID(preReqId);
                }
              }

              if (prereqFailedList != null) {
                // Getting the highest pre-requisites' result
                Integer maxRes = (Integer)preReqResults.lastKey();
                String resString = (String)preReqResults.get(maxRes);
                if (resString.equals(AssertionResult.RESULT_FAILED)
                  ||resString.equals(AssertionResult.RESULT_WARNING)) {
                  resString = AssertionResult.RESULT_PREREQ_FAILED;
                }
                // Create assertion result based on pre-requisites which are not passed
                assertionResult = createAssertionResult(testAssertion, resString, prereqFailedList);
              }

              // Pre-requisites are passed, validate current assertion
              else {

                // Reset test assertion
                assertionProcess.reset();

                //  VERBOSE
                if (verboseOption)
                {
                  System.err.println(
                    "  Processing "
                      + testAssertion.getId()
                      + " for entry reference ID ["
                      + entry.getReferenceID()
                      + "] ...");
                  startTime = System.currentTimeMillis();
                }

                // Validate the target
                assertionResult =
                  assertionProcess.validate(testAssertion, entryContext);

                // Make sure that the XML document cache is updated in the analyzer context
                this.analyzerContext.setDocumentList(documentList);

                //  VERBOSE
                if (verboseOption)
                {
                  System.err.println(
                    "    Elapsed time: "
                      + (System.currentTimeMillis() - startTime)
                      + "ms");
                }                
              }
            }

            // Add result to the report
            reporter.addAssertionResult(assertionResult);
          }

          catch (ClassNotFoundException cnfe)
          {
            // DEBUG:
            if (testAssertion != null)
            {
              reporter
                .getReport()
                .getReportContext()
                .getAnalyzer()
                .printMessage(
                "WARNING: "
                  + testAssertion.getId()
                  + " is not supported currently.");
            }
          }
        }
      }
    }

    catch (Exception e)
    {
      System.err.println("EXECEPTION: " + e.getMessage());
      if (verboseOption)
        e.printStackTrace();

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

    finally
    {
      // Indicate that we are done with this assertion target
      this.reporter.endCurrentEntry();
    }
  }

  /**
   * Determine if the test assertion should be processed for the current entry.
   * @param testAssertion a test assertion.
   * @param entryContext  the entry context.
   * @return true if the test assertion should be processed for the current entry.
   */
  protected abstract boolean isPrimaryEntryTypeMatch(
    TestAssertion testAssertion,
    EntryContext entryContext);

  /**
   * Determine if the test assertion should be processed for the current entry.
   * @param testAssertion  a test assertion.
   * @param entry          an Entry object
   * @return true if the test assertion should be processed for the current entry.
   */
  protected boolean isPrimaryEntryTypeMatch(
    TestAssertion testAssertion,
    Entry entry)
  {
    boolean match = false;

    // If the test assertion entry type matches the target context entry type, then contine
    if (testAssertion
      .getEntryTypeName()
      .equals(entry.getEntryType().getTypeName()))
    {
      match = true;
    }

    return match;
  }

  /**
   * Determine if the test assertion is not applicable.
   * @param testAssertion a test assertion.
   * @return true if the test assertion is not applicable.
   */
  protected abstract boolean isNotApplicable(TestAssertion testAssertion);

  /* (non-Javadoc)
   * @see org.wsi.test.profile.validator.BaseValidator#cleanup()
   */
  public void cleanup() throws WSIException
  {
    // If no assertions were processed, then set all missingInput
    if (assertionCount == 0)
      setAllMissingInput();

    // Set cached document list in case it was updated
    this.analyzerContext.setDocumentList(this.documentList);
  }

  /**
   * Create assertion result.
   * @param testAssertion a test assertion.
   * @param result        a String object.
   * @param failureDetail a FailureDetail object.
   * @return newly created test result.
   */
  public AssertionResult createAssertionResult(
    TestAssertion testAssertion,
    String result,
    FailureDetail failureDetail)
  {
    Vector failureDetailList = null;

    // Create failure detail list
    if (failureDetail != null)
    {
      failureDetailList = new Vector();
      failureDetailList.add(failureDetail);
    }

    return createAssertionResult(testAssertion, result, failureDetailList);
  }

  /**
   * Create assertion result.
   * @param testAssertion         a test assertion.
   * @param result                a String object.
   * @param failureDetailMessage  a failure detail message.
   * @return newly created test result.
   */
  public AssertionResult createAssertionResult(
    TestAssertion testAssertion,
    String result,
    String failureDetailMessage)
  {
    return createAssertionResult(
      testAssertion,
      result,
      failureDetailMessage,
      null);
  }

  /**
   * Create assertion result.
   * @param testAssertion         a test assertion.
   * @param result                a String object.
   * @param failureDetailMessage  a failure detail message.
   * @param elementLocation       element location.
   * @return newly created test result.
   */
  public AssertionResult createAssertionResult(
    TestAssertion testAssertion,
    String result,
    String failureDetailMessage,
    ElementLocation elementLocation)
  {
    // Create failure detail list
    Vector failureDetailList = null;
    if (failureDetailMessage != null)
    {
      failureDetailList = new Vector();
      FailureDetail failureDetail = reporter.createFailureDetail();
      failureDetail.setFailureMessage(failureDetailMessage);
      failureDetail.setElementLocation(elementLocation);
      failureDetailList.add(failureDetail);
    }

    return createAssertionResult(testAssertion, result, failureDetailList);
  }

  /**
   * Create assertion result.
   * @param testAssertion     a test assertion.
   * @param result            a String object.
   * @param failureDetailList a failure detail list.
   * @return newly created test result.
   */
  public AssertionResult createAssertionResult(
    TestAssertion testAssertion,
    String result,
    Vector failureDetailList)
  {
    // Create assertion result
    AssertionResult assertionResult = reporter.createAssertionResult();

    // Set values in assertion result
    assertionResult.setAssertion(testAssertion);
    assertionResult.setResult(result);
    assertionResult.setEntry(reporter.getReport().getCurrentEntry());

    // Set failure detail list
    assertionResult.setFailureDetailList(failureDetailList);

    return assertionResult;
  }

  /**
   * Create assertion result.
   * @param testAssertion     a test assertion.
   * @param result            a String object.
   * @param prereqFailedList  a list failed pre-requisite assertions.
   * @return newly created test result.
   */
  public AssertionResult createAssertionResult(
    TestAssertion testAssertion,
    String result,
    PrereqFailedList prereqFailedList)
  {
    // Create assertion result
    AssertionResult assertionResult = reporter.createAssertionResult();

    // Set values in assertion result
    assertionResult.setAssertion(testAssertion);
    assertionResult.setResult(result);
    assertionResult.setEntry(reporter.getReport().getCurrentEntry());
    assertionResult.setPrereqFailedList(prereqFailedList);

    return assertionResult;
  }

  /**
   * Add assertion result to report.
   * @param assertionId  assertion id.
   * @param result       assertion result.
   * @throws WSIException if the assertion result cannot be added to the report.
   */
  protected void addAssertionResult(String assertionId, String result)
    throws WSIException
  {
    // Create test assertion result
    AssertionResult assertionResult = reporter.createAssertionResult();

    // Set assertion, result and target
    assertionResult.setAssertion(profileArtifact.getTestAssertion(assertionId));
    assertionResult.setResult(result);
    assertionResult.setEntry(reporter.getReport().getCurrentEntry());

    // Add it to the report
    reporter.addAssertionResult(assertionResult);
  }

  /**
   * Add assertion result to report with an error detail message.
   * @param assertionId          assertion id.
   * @param result               assertion result.
   * @param failureDetailMessage an error detail message.
   * @throws WSIException if the assertion result cannot be added to the report.
   */
  protected void addAssertionResult(
    String assertionId,
    String result,
    String failureDetailMessage)
    throws WSIException
  {
    // Convert message to vector
    Vector failureDetailList = null;
    if (failureDetailMessage != null)
    {
      failureDetailList = new Vector();
      FailureDetail failureDetail = reporter.createFailureDetail();
      failureDetailList.add(failureDetail);
    }

    // Add assertion result
    addAssertionResult(assertionId, result, failureDetailList);
  }

  /**
   * Add assertion result to report.
   * @param assertionId        assertion id.
   * @param result             assertion result.
   * @param failureDetailList  a list of error detail messages.
   * @throws WSIException if the assertion result cannot be added to the report.
   */
  protected void addAssertionResult(
    String assertionId,
    String result,
    Vector failureDetailList)
    throws WSIException
  {
    // Create test assertion result
    AssertionResult assertionResult = reporter.createAssertionResult();

    // Set assertion, result and target
    assertionResult.setAssertion(profileArtifact.getTestAssertion(assertionId));
    assertionResult.setResult(result);
    assertionResult.setEntry(reporter.getReport().getCurrentEntry());
    assertionResult.setFailureDetailList(failureDetailList);

    // Add it to the report
    reporter.addAssertionResult(assertionResult);
  }

  /**
   * Add missingInput assertion result to report.
   * @param testAssertion a test assertion.
   * @throws WSIException if there is any problem adding missingInput 
   * 		 assertion result to report.
   */
  protected void addMissingInputResult(TestAssertion testAssertion)
    throws WSIException
  {
    // Create test assertion result
    AssertionResult assertionResult = reporter.createAssertionResult();

    // Set assertion, result and target
    assertionResult.setAssertion(testAssertion);
    assertionResult.setResult(AssertionResult.RESULT_MISSING_INPUT);
    assertionResult.setEntry(reporter.getReport().getCurrentEntry());

    // Add it to the report
    reporter.addAssertionResult(assertionResult);
  }

  /* (non-Javadoc)
   * @see org.wsi.test.profile.validator.BaseValidator#setAllMissingInput()
   */
  public void setAllMissingInput() throws WSIException
  {
    // If profile artifact is set
    if (profileArtifact != null)
    {
      TestAssertion testAssertion;
  
      // Create entry
      Entry entry = this.reporter.getReport().createEntry();
      entry.setArtifactName(this.reportArtifact.getType().getTypeName());
  
      // Add entry to artifact
      this.reportArtifact.addEntry(entry);
  
      // Add entry to report
      this.reporter.setCurrentEntry(entry);
  
      // Go through the list of test assertions for the artifact
      Iterator iterator = profileArtifact.getTestAssertionList().iterator();
      while (iterator.hasNext())
      {
        // Get next test assertion
        testAssertion = (TestAssertion) iterator.next();
  
        // Add missingInput result
        if (testAssertion.isEnabled())
          addMissingInputResult(testAssertion);
      }
  
      // Indicate that we are done with this assertion target
      this.reporter.endCurrentEntry();
    }
  }

  /**
   * Set all results for an entry type to missingInput.
   * @param entryType an EntryType object.
   * @throws WSIException if there is any problem while processing.
   */
  protected void setMissingInput(EntryType entryType) throws WSIException
  {
    TestAssertion testAssertion;

    // Create entry 
    Entry entry = this.reporter.getReport().createEntry();
    entry.setEntryType(entryType);
    entry.setReferenceID("[" + entryType.getTypeName() + "]");

    // Add entry to artifact
    this.reportArtifact.addEntry(entry);

    // Add entry to report
    this.reporter.setCurrentEntry(entry);

    //try {
    // Go through the list of test assertions for the artifact
    Iterator iterator = profileArtifact.getTestAssertionList().iterator();
    while (iterator.hasNext())
    {
      // Get next test assertion
      testAssertion = (TestAssertion) iterator.next();
      if (testAssertion.isEnabled()
        && isPrimaryEntryTypeMatch(testAssertion, entry))
      {
        addMissingInputResult(testAssertion);
      }
    }

    // Indicate that we are done with this entry
    this.reporter.endCurrentEntry();
  }
}
