/*******************************************************************************
 * Copyright (c) 2002, 2010 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;

    // 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);

                //  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();
	  analyzerContext = null;
	  profileArtifact = null;
	  reportArtifact = null;
	  reporter = null;
  }

  /**
   * 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();
  }
}
