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

import java.io.Reader;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.TreeMap;

import org.eclipse.wst.wsi.internal.core.WSIConstants;
import org.eclipse.wst.wsi.internal.core.WSIException;
import org.eclipse.wst.wsi.internal.core.profile.EntryTypeList;
import org.eclipse.wst.wsi.internal.core.profile.ProfileArtifact;
import org.eclipse.wst.wsi.internal.core.profile.ProfileAssertions;
import org.eclipse.wst.wsi.internal.core.profile.ProfileAssertionsReader;
import org.eclipse.wst.wsi.internal.core.profile.TestAssertion;
import org.eclipse.wst.wsi.internal.core.util.ArtifactType;
import org.eclipse.wst.wsi.internal.core.util.Utils;
import org.eclipse.wst.wsi.internal.core.xml.XMLUtils;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

/**
 * This class ...
 * 
 * @version 1.0.1
 * @author Peter Brittenham  (peterbr@us.ibm.com)
 */
public class ProfileAssertionsReaderImpl implements ProfileAssertionsReader
{
  /**
   * Profile assertions.
   */
  protected ProfileAssertions profileAssertions;

  /**
   * ReportArtifact list.
   */
  protected TreeMap artifactList = new TreeMap();

  /**
   * Create new reader.
   */
  public ProfileAssertionsReaderImpl()
  {
  }

  /* (non-Javadoc)
   * @see org.wsi.test.profile.ProfileAssertionsReader#readProfileAssertions(String)
   */
  public ProfileAssertions readProfileAssertions(String assertionsURI)
    throws WSIException
  {
    return readProfileAssertions(new InputSource(assertionsURI));
  }

  /* (non-Javadoc)
   * @see org.wsi.test.profile.ProfileAssertionsReader#readProfileAssertions(Reader)
   */
  public ProfileAssertions readProfileAssertions(Reader reader)
    throws WSIException
  {
    return readProfileAssertions(new InputSource(reader));
  }

  /**
   * Read profile assertions.
   */
  private ProfileAssertions readProfileAssertions(InputSource inputSource)
    throws WSIException
  {
    // Create profile assertions
    profileAssertions = new ProfileAssertionsImpl();

    // Profile parts are put into a vector
    artifactList = new TreeMap();

    try
    {
      // Create xml reader
      XMLReader reader = XMLUtils.getXMLReader();

      // Set content handler to inner class
      reader.setContentHandler(new ProfileAssertionsHandler());

      // Parse profile definition file
      reader.parse(inputSource);
    }

    catch (Exception e)
    {
      throw new WSIException("Could not read and parse profile definition.", e);
    }
    finally
    {
      //Check to see if the version of test asssertion document is supported
      if (!Utils.isValidProfileTADVersion(profileAssertions))
      {
        throw new WSIException(
          "\nVersion "
            + profileAssertions.getTADVersion()
            + " of the \""
            + profileAssertions.getTADName()
            + "\"\n"
            + "document is not compatible with this version of"
            + "\n"
            + "the test tools.");
      }
    }

    // The assertions from the TAD are reordered for purposes of processing. All
    // assertions of an artifact are reordered such that prerequisites occur
    // before the assertions they prereq. The assumption is that  prerequisites do
    // not cross artifact types.
    //
    Iterator it = artifactList.keySet().iterator();
    // for each artifact type do reordering assertion 
    while (it.hasNext())
    {
      ProfileArtifact art = (ProfileArtifact) artifactList.get(it.next());
      // result list of the reordering assertions 
      LinkedList res = new LinkedList();
      Iterator it2 = art.getTestAssertionList().iterator();
      // sort the artifact assertions into result list 
      while (it2.hasNext())
      {
        // call for each assertion , 
        // if the assertion has the prereq, the prereq will added first into res list
        sortTestAssertions(art, (TestAssertion) it2.next(), res);
      }
      // replace the original assertions list to the prereq reordering assertions list
      art.getTestAssertionList().clear();
      art.getTestAssertionList().addAll(res);
    }
    // Put the profile parts into the profile definition
    profileAssertions.setArtifactList(artifactList);

    return profileAssertions;
  }
  
  /* (non-Javadoc)
   * @see org.wsi.test.document.DocumentReader#getLocation()
   */
  public String getLocation()
  {
    return null;
  }

  /* (non-Javadoc)
   * @see org.wsi.test.document.DocumentReader#setLocation(String)
   */
  public void setLocation(String documentURI)
  {
  }

  /**
   * Recursive walk to order assertions so that assertions are 
   * processed following the ones that prereq them.
   * If assertion has prereq, then add it to the result list first.
   *  
   * @param art profile artifact for call @link ProfileArtifact#getTestAssertion(String)
   * @param asrt test assertion
   * @param list result list to sort
   */
  private void sortTestAssertions(ProfileArtifact art, TestAssertion asrt, List list)
  {
    // if assertion is null or does not exist, then exit
    if((asrt == null) || list.contains(asrt)) 
      return;
    
    // if it has not prereq, add the asertion and exit
    if(asrt.getPrereqIdList().isEmpty()) 
    {
      list.add(asrt);
      return;
    }
    // get list prereq assertion and reqursive call sortTestAssertions this each    
    Iterator it = asrt.getPrereqIdList().iterator();
    while(it.hasNext()) {
      String id = (String) it.next();
      sortTestAssertions(art, art.getTestAssertion(id), list);
    }
    list.add(asrt);
  }

  /**
   * Inner class: ProfileAssertionsHandler
   */
  class ProfileAssertionsHandler extends DefaultHandler
  {
    private ProfileArtifact artifact = profileAssertions.createArtifact();
    private String id;
    private StringBuffer context = null;
    private StringBuffer assertionDescription = null;
    private StringBuffer failureMessage = null;
    private StringBuffer failureDetailDescription = null;
    private StringBuffer detailDescription = null;
    private StringBuffer testAssertionId = null;
    //    private Vector prereqIdList = new Vector();
    private TreeMap assertions = new TreeMap();
    private String currentElement = null;
    private TestAssertion testAssertion = null;
    private StringBuffer logInput = null;
    private StringBuffer wsdlInput = null;
    private StringBuffer uddiInput = null;
    private EntryTypeList entryTypeList = null;

    // Process start element event
    public void startElement(
      String namespaceURI,
      String localName,
      String qName,
      Attributes atts)
    {
      if (namespaceURI != null
        && (namespaceURI.equals(WSIConstants.NS_URI_WSI_ASSERTIONS_2003)
        ||  namespaceURI.equals(WSIConstants.NS_URI_WSI_ASSERTIONS)))
      {
        // Save element name
        currentElement = localName;

        // <artifact>
        if (localName.equals(WSIConstants.ELEM_ARTIFACT))
        {
          // Create a new profile artifact object
          artifact = profileAssertions.createArtifact();

          // Set type
          artifact.setType(
            ArtifactType.newArtifactType(
              atts.getValue(WSIConstants.ATTR_TYPE)));

          // ADD: Get specification list

          // Add artifact to list of artifact list
          artifactList.put(artifact.getType().getTypeName(), artifact);
        }

        // <testAssertion>
        else if (localName.equals(WSIConstants.ELEM_TEST_ASSERTION))
        {
          // Create test assertion
          testAssertion = new TestAssertionImpl();

          // Get attribute values
          testAssertion.setId(atts.getValue("", WSIConstants.ATTR_ID));
          testAssertion.setType(atts.getValue("", WSIConstants.ATTR_TYPE));
          testAssertion.setEntryTypeName(
            atts.getValue("", WSIConstants.ATTR_ENTRY_TYPE));
          testAssertion.setEnabled(
            Boolean
              .valueOf(atts.getValue("", WSIConstants.ATTR_ENABLED))
              .booleanValue());

          // Add test assertion to artifact
          artifact.addTestAssertion(testAssertion);
        }

        // <context>
        else if (localName.equals(WSIConstants.ELEM_CONTEXT))
        {
          context = new StringBuffer();
        }

        // <assertionDescription>
        else if (localName.equals(WSIConstants.ELEM_ASSERTION_DESCRIPTION))
        {
          assertionDescription = new StringBuffer();
        }

        // <failureMessage>
        else if (localName.equals(WSIConstants.ELEM_FAILURE_MESSAGE))
        {
          failureMessage = new StringBuffer();
        }

        // <failureDetailDescription>
        else if (localName.equals(WSIConstants.ELEM_FAILURE_DETAIL_DESCRIPTION))
        {
          failureDetailDescription = new StringBuffer();
        }

        // <detailDescription>
        else if (localName.equals(WSIConstants.ELEM_DETAIL_DESCRIPTION))
        {
          detailDescription = new StringBuffer();
        }

        // <testAssertionID>
        else if (localName.equals(WSIConstants.ELEM_TEST_ASSERTION_ID))
        {
          testAssertionId = new StringBuffer();
        }

        // <additionalEntryTypeList>
        else if (
          localName.equals(WSIConstants.ELEM_ADDITIONAL_ENTRY_TYPE_LIST))
        {
          // Create entry type list
          entryTypeList = new EntryTypeListImpl();
        }

        // <messageInput>
        else if (localName.equals(WSIConstants.ELEM_MESSAGE_INPUT))
        {
          logInput = new StringBuffer();
        }

        // <wsdlInput>
        else if (localName.equals(WSIConstants.ELEM_WSDL_INPUT))
        {
          wsdlInput = new StringBuffer();
        }
        // <profileAssertions>
        else if (localName.equals(WSIConstants.ELEM_PROFILE_ASSERTIONS))
        {
          profileAssertions.setTADName(
            atts.getValue("", WSIConstants.ATTR_NAME));
          profileAssertions.setTADVersion(
            atts.getValue("", WSIConstants.ATTR_VERSION));
        }

        /* REMOVE:     
        // <uddiInput>
        else if (localName.equals(WSIConstants.ELEM_UDDI_INPUT)) {
          uddiInput = new StringBuffer();
        } 
        */
      }
    } // END startElement

    public void endElement(String namespaceURI, String localName, String qname)
    {
      // If this is the profile namespace, then check for and process selected elements
      if (namespaceURI != null
        && (namespaceURI.equals(WSIConstants.NS_URI_WSI_ASSERTIONS_2003)
        || namespaceURI.equals(WSIConstants.NS_URI_WSI_ASSERTIONS)))
      {
        // <context>
        if (localName.equals(WSIConstants.ELEM_CONTEXT))
        {
          // Set context in test assertion
          testAssertion.setContext(context.toString());
          context = null;
        }

        // <assertionDescription>
        else if (localName.equals(WSIConstants.ELEM_ASSERTION_DESCRIPTION))
        {
          // Set assertion description in test assertion
          testAssertion.setAssertionDescription(
            assertionDescription.toString());
          assertionDescription = null;
        }

        // <failureMessage>
        else if (localName.equals(WSIConstants.ELEM_FAILURE_MESSAGE))
        {
          // Set failure message in test assertion
          testAssertion.setFailureMessage(failureMessage.toString());
          failureMessage = null;
        }

        // <failureDetailDescription>
        else if (localName.equals(WSIConstants.ELEM_FAILURE_DETAIL_DESCRIPTION))
        {
          // Set failure detail description in test assertion
          testAssertion.setFailureDetailDescription(
            failureDetailDescription.toString());
          failureDetailDescription = null;
        }

        // <detailDescription>
        else if (localName.equals(WSIConstants.ELEM_DETAIL_DESCRIPTION))
        {
          // Set detail description in test assertion
          testAssertion.setDetailDescription(detailDescription.toString());
          detailDescription = null;
        }

        // <testAssertionID>
        else if (localName.equals(WSIConstants.ELEM_TEST_ASSERTION_ID))
        {
          // Set test assertion id in prereq list
          testAssertion.addPrereqId(testAssertionId.toString());
          testAssertionId = null;
        }

        // <addtionalEntryTypeList>
        else if (
          localName.equals(WSIConstants.ELEM_ADDITIONAL_ENTRY_TYPE_LIST))
        {
          // Set target list
          testAssertion.setAdditionalEntryTypeList(entryTypeList);
          entryTypeList = null;
        }

        // <messageInput>
        else if (localName.equals(WSIConstants.ELEM_MESSAGE_INPUT))
        {
          // Set test assertion id in prereq list
          entryTypeList.setLogInput(logInput.toString());
          logInput = null;
        }

        // <wsdlInput>
        else if (localName.equals(WSIConstants.ELEM_WSDL_INPUT))
        {
          // Set test assertion id in prereq list
          entryTypeList.setWSDLInput(wsdlInput.toString());
          wsdlInput = null;
        }

        // <profileAssertions>
        else if (localName.equals(WSIConstants.ELEM_PROFILE_ASSERTIONS))
        {
          // a no-op
        }

        /* REMOVE:
        // <uddiInput>
        else if (localName.equals(WSIConstants.ELEM_UDDI_INPUT)) {
          // Set test assertion id in prereq list
           entryTypeList.setUDDIInput(uddiInput.toString());         
          uddiInput = null;
        }
        */
      }
    } // END endElement

    public void characters(char[] ch, int start, int length)
    {
      // <context>
      if ((context != null)
        && (currentElement.equals(WSIConstants.ELEM_CONTEXT)))
      {
        context.append(ch, start, length);
      }

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

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

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

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

      // <testAssertionID>
      else if (
        (testAssertionId != null)
          && (currentElement.equals(WSIConstants.ELEM_TEST_ASSERTION_ID)))
      {
        testAssertionId.append(ch, start, length);
      }

      // <messageInput>
      else if (
        (logInput != null)
          && (currentElement.equals(WSIConstants.ELEM_MESSAGE_INPUT)))
      {
        logInput.append(ch, start, length);
      }

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

      /* REMOVE:
      // <uddiInput>
      else if ((uddiInput != null) && (currentElement.equals(WSIConstants.ELEM_UDDI_INPUT))) {
        uddiInput.append(ch, start, length);
      }
      */
    }
  }
}
