/*******************************************************************************
 * Copyright (c) 2001, 2004 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 Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.wst.wsdl.validation.internal;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.ResourceBundle;

import org.apache.xerces.impl.XMLErrorReporter;
import org.apache.xerces.parsers.DOMParser;
import org.apache.xerces.parsers.StandardParserConfiguration;
import org.apache.xerces.xni.XNIException;
import org.apache.xerces.xni.grammars.XMLGrammarPool;
import org.eclipse.wst.wsdl.validation.internal.exception.ValidateWSDLException;
import org.eclipse.wst.wsdl.validation.internal.resolver.URIResolver;
import org.eclipse.wst.wsdl.validation.internal.util.MessageGenerator;
import org.eclipse.wst.wsdl.validation.internal.xml.AbstractXMLConformanceFactory;
import org.eclipse.wst.wsdl.validation.internal.xml.DefaultXMLValidator;
import org.eclipse.wst.wsdl.validation.internal.xml.IXMLValidator;
import org.eclipse.wst.wsdl.validation.internal.xml.LineNumberDOMParser;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;

/**
 * This is the main entrypoint to the WSDL Validator. The controller is
 * responsible for calling the reader, the XML conformance check, the WSDL
 * validation and the WS-I validation if selected. The controller contains any
 * errors and warnings generated as well.
 */
public class ValidationController
{
  protected final String _ERROR_PROBLEM_WSDL_VALIDATOR = "_ERROR_PROBLEM_WSDL_VALIDATOR";
  protected final String _ERROR_NO_WSDL_VALIDATOR = "_ERROR_NO_WSDL_VALIDATOR";
  protected final String _ERROR_PROBLEM_EXT_VALIDATOR = "_ERROR_PROBLEM_EXT_VALIDATOR";

  protected ValidatorRegistry ver;
  protected ResourceBundle resourcebundle;
  protected MessageGenerator messagegenerator;
  protected URIResolver uriResolver;
  protected Hashtable attributes = new Hashtable();

  //protected String wsdlNamespace = null;

  /**
   * The ResourceBundle needs to be set so it can be passed to the reader.
   * 
   * @param rb
   *            The resource bundle for this validator.
   */
  public ValidationController(ResourceBundle rb, URIResolver uriResolver)
  {
    resourcebundle = rb;
    messagegenerator = new MessageGenerator(resourcebundle);
    this.uriResolver = uriResolver;

    ver = ValidatorRegistry.getInstance();
  }
  
  /**
   * Add the attributes specified to the validation.
   * 
   * @param attributes The attributes to add to the validation.
   */
  public void setAttributes(Hashtable attributes)
  {
  	this.attributes.putAll(attributes);
  }

  /**
   * Validate the WSDL file. Check the file for XML conformance. If it is XML
   * conformant, read the file and check it for WSDL conformance. If it is WSDL
   * conformant and WS-I conformance is set to suggest or require, check the
   * file for WS-I conformance.
   * 
   * @param uri
   *            The uri where the WSDL document is located.
   * @param wsiLevel
   *            The level of WS-I conformance to use for validation.
   * @return A validation report with the validation info for the file.
   */
//  public IValidationReport validate(String uri)
//  { return validate(uri, null);
//  }
  
  /**
   * Validate the WSDL file with the stream. This method will run the check of the 
   * WSDL document. The validation is broken up into three stages: XML conformance,
   * WSDL semantic, and post validation.
   * 
 * @param uri The URI of the WSDL document to be validated.
 * @param inputStream The contents of the WSDL document to be validated.
 * @return A validation report with the validation info for the file.
 */
  public IValidationReport validate(String uri, InputStream inputStream)
  {
    
    InputStream xmlValidateStream = null;
    InputStream wsdlValidateStream = null;
    if (inputStream != null)
    { //copy the inputStream so we can use it more than once
      String contents = createStringForInputStream(inputStream);
      xmlValidateStream = new ByteArrayInputStream(contents.getBytes());
      wsdlValidateStream = new ByteArrayInputStream(contents.getBytes());
    }
    
    ControllerValidationInfo valInfo = new ValidationInfoImpl(uri, messagegenerator);
    ((ValidationInfoImpl)valInfo).setURIResolver(uriResolver);
    ((ValidationInfoImpl)valInfo).setAttributes(attributes);

    if (validateXML(valInfo, xmlValidateStream))
    {
      Document wsdldoc = getDocument(uri, wsdlValidateStream);

      String wsdlns = getWSDLNamespace(wsdldoc);
      if(wsdlns != null)
      {
        if (validateWSDL(wsdldoc, valInfo, wsdlns))
        {
          validateExtensionValidators(wsdldoc, valInfo, wsdlns);
        }
      }
    }
    return valInfo;
  }

  /**
   * Validate the file for XML conformance.
	 * @param valInfo information about the validation
   * @param inputStream the inputStream to validate
   * @return True if the file is conformant, false otherwise.
   */
  protected boolean validateXML(ControllerValidationInfo valInfo, InputStream inputStream)
  {
    IXMLValidator xmlValidator = AbstractXMLConformanceFactory.getInstance().getXMLValidator();
    xmlValidator.setURIResolver(uriResolver);
    xmlValidator.setFile(valInfo.getFileURI());
    if (xmlValidator instanceof DefaultXMLValidator)
    {
        ((DefaultXMLValidator)xmlValidator).setInputStream(inputStream);
        XMLGrammarPool grammarPool = (XMLGrammarPool)valInfo.getAttribute(Constants.XML_CACHE_ATTRIBUTE);
        if(grammarPool != null)
          ((DefaultXMLValidator)xmlValidator).setGrammarPool(grammarPool);
    }
    //xmlValidator.setValidationInfo(valInfo);
    xmlValidator.run();
    // if there are no xml conformance problems go on to check the wsdl stuff
    if (xmlValidator.hasErrors())
    {
      // temp handling of XML errors until validator is updated.
      List errors = xmlValidator.getErrors();
      Iterator errorsIter = errors.iterator();
      while (errorsIter.hasNext())
      {
        IValidationMessage valMes = (IValidationMessage)errorsIter.next();
        
        if (valMes instanceof ValidationMessageImpl && valInfo instanceof ValidationInfoImpl)
        {   String errorKey = ((ValidationMessageImpl)valMes).getErrorKey();
            Object[] messageArgs = ((ValidationMessageImpl)valMes).getMessageArguments();
            ((ValidationInfoImpl)valInfo).addError(valMes.getMessage(), valMes.getLine(), valMes.getColumn(), valMes.getURI(), errorKey, messageArgs);
        }
        else
        {
            valInfo.addError(valMes.getMessage(), valMes.getLine(), valMes.getColumn(), valMes.getURI());
        }
      }
      return false;
    }
    //wsdlNamespace = xmlValidator.getWSDLNamespace();
    return true;
  }
  
  /**
   * Validate the file for XML conformance.
	 * @param valInfo information about the validation
   * @return True if the file is conformant, false otherwise.
   */
  protected boolean validateXML(ControllerValidationInfo valInfo)
  { return validateXML(valInfo, null);
  }

  /**
   * Validate the WSDL file. Set the errors and warning appropriately.
   * 
   * @param wsdldoc A W3C document representation of the WSDL document.
   * @param valInfo The current validation information.
   * @param wsdlNamespace The WSDL namespace to validate.
   * @return True if the file is valid, false otherwise.
   */
  protected boolean validateWSDL(Document wsdldoc, ControllerValidationInfo valInfo, String wsdlNamespace)
  {
    WSDLValidatorDelegate[] wsdlVals = ver.queryValidatorRegistry(wsdlNamespace, ValidatorRegistry.WSDL_VALIDATOR);
    if (wsdlVals != null)
    {
      for (int i = 0; i < wsdlVals.length; i++)
      {
        WSDLValidatorDelegate wsdlvaldel = wsdlVals[i];
        IWSDLValidator wsdlVal = wsdlvaldel.getValidator();

        // If the wsdl validator isn't null, validate.
        if (wsdlVal != null)
        {
          try
          {
            wsdlVal.validate(wsdldoc, valInfo);
          }
          catch (ValidateWSDLException e)
          {
            valInfo.addError(messagegenerator.getString(_ERROR_PROBLEM_WSDL_VALIDATOR, wsdlNamespace), 1, 1, valInfo.getFileURI());
          }
        }
        // If the validator is null and the namespace isn't create an error.
        // If the namespace is null the file is empty (and the XML validator
        // has let it go)
        // so it is valid but does not need to be validated.
        else
        {
          valInfo.addError(
            messagegenerator.getString(_ERROR_NO_WSDL_VALIDATOR, wsdlNamespace),
            1,
            1,
            valInfo.getFileURI());
        }
      }
    }
    // No validators registered.
    else
    {
      valInfo.addError(messagegenerator.getString(_ERROR_NO_WSDL_VALIDATOR, wsdlNamespace), 1, 1, valInfo.getFileURI());
    }
    valInfo.completeWSDLValidation();

    return valInfo.isWSDLValid();
  }

  /**
   * Validate the WSDL file with the extension validator. Set the errors and warning appropriately.
   * 
   * @param wsdldoc A W3C document representation of the WSDL document.
   * @param valInfo The current validation information.
   * @param wsdlNamespace The WSDL namespace to validate.
   * @return True if the file is valid, false otherwise.
   */
  protected void validateExtensionValidators(Document wsdldoc, ControllerValidationInfo valInfo, String wsdlNamespace)
  {
    WSDLValidatorDelegate[] extVals = ver.queryValidatorRegistry(wsdlNamespace, ValidatorRegistry.EXT_VALIDATOR);
    if(extVals != null)
    {
      int numvals = extVals.length;
      for(int i = 0; i < numvals; i++)
      {
        WSDLValidatorDelegate extvaldel = extVals[i];
        IWSDLValidator extval = extvaldel.getValidator();
        if(extval != null)
        {
          try
          {
          extval.validate(wsdldoc, valInfo);
          }
          catch(Throwable  t)
          {
            valInfo.addWarning(messagegenerator.getString(_ERROR_PROBLEM_EXT_VALIDATOR,  extvaldel.getValidatorClassName(), wsdlNamespace), 1, 1, valInfo.getFileURI());
            // This error should be logged and not displayed to the user.
          }
        }
      }
    }
  }

  /**
   * Set the ResourceBundle for this ValidatorManager.
   * 
   * @param rb
   *            The resource bundle to set.
   * @see #getResourceBundle
   */
  public void setResourceBundle(ResourceBundle rb)
  {
    resourcebundle = rb;
  }

  /**
   * Get the ResourceBundle for this ValidationController.
   * 
   * @return The resource bundle set for this ValidationController.
   * @see #setResourceBundle
   */
  public ResourceBundle getResourceBundle()
  {
    return resourcebundle;
  }
  
  /**
   * Get a DOM document representation of the WSDL document.
   * 
   * @param uri The uri of the file to read
   * @return The DOM model of the WSDL document or null if the document can't be read.
   */
  private Document getDocument(String uri, InputStream inputStream)
  {
    try
    {
      // Catch a premature EOF error to allow empty WSDL files to be considered valid.
      StandardParserConfiguration configuration = new StandardParserConfiguration()
      {
        protected XMLErrorReporter createErrorReporter()
        {
          return new XMLErrorReporter()
          {
            public void reportError(String domain, String key, Object[] arguments, short severity) throws XNIException
            {
              boolean reportError = true;
              if (key.equals("PrematureEOF"))
              {         
                reportError = false;
              }

              if (reportError)
              {
                super.reportError(domain, key, arguments, severity);
              }
            }
          };
        }
      };
      
      InputSource inputSource = null;
      if (inputStream != null)
      { //then we want to create a DOM from the inputstream
        inputSource = new InputSource(inputStream);
      }
      else
      { inputSource = new InputSource(uri);
      }
      
      DOMParser builder = new LineNumberDOMParser(configuration);
      builder.parse(inputSource);
      Document doc = builder.getDocument();

      return doc;
    }
    catch (Throwable t)
    {
    	// TODO: Log error if the parser fails to read the WSDL document.
    	// In this case the validator will fail with an unexplained error message
    	// about a null WSDL namespace. This error should be addressed as well.
    	System.out.println(t);
    }
    return null;
  }
  
  private String getWSDLNamespace(Document doc)
  {
    String wsdlns = null;
    if(doc != null)
    {
      Element rootdoc = doc.getDocumentElement();
      if(rootdoc != null)
      {
        wsdlns = rootdoc.getNamespaceURI();
      }
    }
    return wsdlns;
  }
  
  
  
  private final String createStringForInputStream(InputStream inputStream)
  {
    // Here we are reading the file and storing to a stringbuffer.
    StringBuffer fileString = new StringBuffer();
    try
    {
      InputStreamReader inputReader = new InputStreamReader(inputStream);
      BufferedReader reader = new BufferedReader(inputReader);
      char[] chars = new char[1024];
      int numberRead = reader.read(chars);
      while (numberRead != -1)
      {
        fileString.append(chars, 0, numberRead);
        numberRead = reader.read(chars);
      }
    }
    catch (Exception e)
    {
      //TODO: log error message
      //e.printStackTrace();
    }
    return fileString.toString();
  }
  
}
