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

import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;

import javax.wsdl.Definition;
import javax.wsdl.Types;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.wsdl.extensions.UnknownExtensibilityElement;

import org.eclipse.wst.wsi.internal.core.WSIException;
import org.eclipse.wst.wsi.internal.core.WSITag;
import org.eclipse.wst.wsi.internal.core.profile.TestAssertion;
import org.eclipse.wst.wsi.internal.core.profile.validator.EntryContext;
import org.eclipse.wst.wsi.internal.core.profile.validator.impl.AssertionProcess;
import org.eclipse.wst.wsi.internal.core.report.AssertionResult;
import org.eclipse.wst.wsi.internal.core.util.ErrorList;
import org.eclipse.wst.wsi.internal.core.util.StringTokenizer;
import org.eclipse.wst.wsi.internal.core.xml.XMLUtils;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;


/**
 * BP2202.
 *  <context>For a candidate wsdl:types element within a WSDL document which imports an XML schema directly or indirectly.</context>
 * <assertionDescription>The imported schema uses UTF-8 or UTF-16 for the encoding.</assertionDescription>
 */
public class BP2202 extends AssertionProcess implements WSITag
{
  private final WSDLValidatorImpl validator;

  /**
   * @param WSDLValidatorImpl
   */
  public BP2202(WSDLValidatorImpl impl)
  {
    super(impl);
    this.validator = impl;
  }

  private ErrorList errors = new ErrorList();
  private boolean importFound = false;

  private final char[] OMMITED_XML_DECLARATION_DELIMITERS =
    new char[] { 0x20, 0x9, 0xD, 0xA, '\'', '\"' };
  private final char[] XML_DECLARATION_DELIMITERS = new char[] { '=' };
  private final String UTF_8_ENCODING = "UTF-8";
  private final String UTF_16_ENCODING = "UTF-16";

  private final String ENCODING_TOKEN = "encoding";

  /* (non-Javadoc)
   * @see org.wsi.test.profile.validator.impl.BaseValidatorImpl.AssertionProcess#validate(org.wsi.test.profile.TestAssertion, org.wsi.test.profile.validator.EntryContext)
   */
  public AssertionResult validate(
    TestAssertion testAssertion,
    EntryContext entryContext)
    throws WSIException
  {
    result = result = AssertionResult.RESULT_NOT_APPLICABLE;

    //Definition def = (Definition) entryContext.getEntry().getEntryDetail();
    Types types = (Types) entryContext.getEntry().getEntryDetail();
    List exts = null;
    //if (def.getTypes() != null)
    if (types != null)
      //exts = def.getTypes().getExtensibilityElements();
      exts = types.getExtensibilityElements();
    if (exts != null)
    {
      Definition definition = null;
      if ((definition =
        validator.analyzerContext.getCandidateInfo().getDefinition(types))
        == null)
      {
        throw new WSIException("Could not find types definition in any WSDL document.");
      }

      Iterator it = exts.iterator();
      while (it.hasNext())
      {
        ExtensibilityElement el = (ExtensibilityElement) it.next();
        if (el instanceof UnknownExtensibilityElement
          && el.getElementType().equals(ELEM_XSD_SCHEMA))
          searchForSchema(((UnknownExtensibilityElement) el).getElement(),
              definition.getDocumentBaseURI());
      }
    }

    if (!errors.isEmpty())
    {
      result = AssertionResult.RESULT_FAILED;
      failureDetail = this.validator.createFailureDetail(errors.toString(), entryContext);
    }

    else if (!importFound)
      result = AssertionResult.RESULT_NOT_APPLICABLE;

    else
      result = AssertionResult.RESULT_PASSED;

    return validator.createAssertionResult(testAssertion, result, failureDetail);
  }

  /*
   * Search xsd schema or xsd import from node. If node is xsd import it's loading schema.
   * @param n - node
  */
  private void searchForSchema(Node n, String context)
  {
    while (n != null)
    {
      // searches for xsd:import element
      if (Node.ELEMENT_NODE == n.getNodeType())
      {
        // if xsd:schema element is found -> process schema
        if (XMLUtils.equals(n, ELEM_XSD_SCHEMA))
        {
          processSchema(n, context);
        }
        else
        {
          // if xsd:import element is found -> load schema and process schema
          if (XMLUtils.equals(n, ELEM_XSD_IMPORT))
          {
            importFound = true;
            loadSchema(n, context);
          }
          else
            // else iterate element recursively
            searchForSchema(n.getFirstChild(), context);
        }
      }
      n = n.getNextSibling();
    }
  }

  /*
   * It loads xsd schema and then check valid encoding and looking for xsd:schema element for next process. 
   * @param importNode - xsd schema
  */
  private void loadSchema(Node importNode, String context)
  {
    Element im = (Element) importNode;
    Attr schemaLocation = XMLUtils.getAttribute(im, ATTR_XSD_SCHEMALOCATION);
    // try to parse imported XSD
    if (schemaLocation != null && schemaLocation.getValue() != null)
      try
      {
        // if any error or root element is not XSD schema -> error
        String decl =
          readXMLDeclarationStatement(schemaLocation.getValue(), context);
        if (!validDeclaration(decl,
          ENCODING_TOKEN,
          new String[] { UTF_8_ENCODING, UTF_16_ENCODING }))
        {
          Attr a = XMLUtils.getAttribute(im, ATTR_XSD_NAMESPACE);
          errors.add((a != null) ? a.getValue() : "");
        }

        if (!validDeclaration(decl, "version", new String[] { "1.0" }))
        {
          errors.add(
            "Version number in XML declaration is not 1.0.  XML schema file: "
              + schemaLocation.getValue());
        }

        // DEBUG:
        // System.out.println(schemaLocation.getValue() + ":" + context);

        Document schema =
          validator.parseXMLDocumentURL(schemaLocation.getValue(), context);

        if (XMLUtils.equals(schema.getDocumentElement(), ELEM_XSD_SCHEMA))
        {
           processSchema(schema.getDocumentElement(),
              XMLUtils.createURLString(schemaLocation.getValue(), context));
        }
        result = result = AssertionResult.RESULT_PASSED;
      }
      catch (Throwable t)
      {
      }
  }

  /**
  * Reads an XML declaration statement.
  * @param location
  * @return String
  */
  private String readXMLDeclarationStatement(String location, String baseURI)
  {
    String result = null;
    try
    {
      new URL(location);
    }
    catch (Throwable t)
    {
      // nothing
      int i = baseURI.lastIndexOf('/');
      int j = baseURI.lastIndexOf('\\');
      if (j > i)
        i = j;
      location = baseURI.substring(0, i + 1) + location;
    }

    if (location != null)
    {
      URL url = null;
      Reader reader = null;

      try
      {
        try
        {
          url = new URL(location);
        }
        catch (MalformedURLException e)
        {
          // we should try to access location as file
        }

        if (url != null)
        {
          reader = new InputStreamReader(url.openStream());
        }
        else
        {
          reader = new InputStreamReader(new FileInputStream(location));
        }

        int charCode;
        boolean end = false;
        if (reader.ready())
        {
          charCode = reader.read();

          while (reader.ready() && !(charCode == '<'))
          {
            charCode = reader.read();
          }

          StringBuffer buf = new StringBuffer();
          if (charCode == '<')
          {
            buf.append((char) charCode);
            while (reader.ready() && !end)
            {
              charCode = reader.read();
              buf.append((char) charCode);

              end = charCode == '>';
            }
          }
          else
          {
            // NOTE: This result does not get propogated back!
            result = AssertionResult.RESULT_FAILED;
            failureDetailMessage =
              "Cannot read the XML declaration statement.";
          }

          result = buf.toString();
        }
      }
      catch (Exception e)
      {
        errors.add(e.getMessage());
      }
      finally
      {
        if (reader != null)
        {
          try
          {
            reader.close();
          }
          catch (Throwable e)
          {
          }
        }
      }
    }

    return result;
  }

  /*
   * @param xmlDecl - xml declaration
   * @return if xml declaration contains encoding="utf-16" or encoding="utf-8" it retirns true. 
  */

  //private boolean validEncoding(String xmlDecl)
  //{
  //  //boolean result = false;
  //  boolean result = true;
  //  if (xmlDecl != null)
  //  {
  //    StringTokenizer st =
  //      new StringTokenizer(
  //        OMMITED_XML_DECLARATION_DELIMITERS,
  //        XML_DECLARATION_DELIMITERS);
  //    Enumeration tokens = st.parse(xmlDecl);
  //   boolean found = false;
  //    while (tokens.hasMoreElements() && !found)
  //    {
  //      String token = (String) tokens.nextElement();
  //
  //      if (token.equals(ENCODING_TOKEN))
  //      {
  //        found = true;
  //
  //        tokens.nextElement();
  //        String enc = (String) tokens.nextElement();
  //
  //        result =
  //         UTF_8_ENCODING.equalsIgnoreCase(enc)
  //            || UTF_16_ENCODING.equalsIgnoreCase(enc);
  //      }
  //    }
  //  }
  //
  //  return result;
  //}

  /**
   * @param xmlDecl - xml declaration
   * @return if xml declaration contains valid version number then true is returned. 
  */
  private boolean validDeclaration(
    String xmlDecl,
    String tokenName,
    String[] checkValueList)
  {
    //boolean result = false;
    boolean result = true;
    if (xmlDecl != null)
    {
      StringTokenizer st =
        new StringTokenizer(
          OMMITED_XML_DECLARATION_DELIMITERS,
          XML_DECLARATION_DELIMITERS);
      Enumeration tokens = st.parse(xmlDecl);

      if (tokens.hasMoreElements())
      {
        boolean found = false;
        while (tokens.hasMoreElements() && !found)
        {
          String token = (String) tokens.nextElement();

          if (token.equals(tokenName))
          {
            found = true;
            result = false;

            tokens.nextElement();
            String tokenValue = (String) tokens.nextElement();

            for (int i = 0; i < checkValueList.length && !result; i++)
            {
              if (checkValueList[i].equalsIgnoreCase(tokenValue))
                result = true;
            }
          }
        }
      }

      // If there are no tokens then it is not a valid declaraction
      else
      {
        result = false;
      }
    }

    return result;
  }

  /*
   * It's looking for xsd import and load it if find.
   * @param schema - xsd schema
   * @param namespace - namespace of schema
   */
  private void processSchema(Node schema, String context)
  {
    Node n = schema.getFirstChild();
    while (n != null)
    {
      if (Node.ELEMENT_NODE == n.getNodeType()
        && XMLUtils.equals(n, ELEM_XSD_IMPORT))
      {
        importFound = true;
        loadSchema(n, context);
      }

      n = n.getNextSibling();
    }
  }

}