/*******************************************************************************
 * 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.validate.wsdl;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ResourceBundle;

import javax.wsdl.Binding;
import javax.wsdl.Definition;
import javax.wsdl.Message;
import javax.wsdl.Port;
import javax.wsdl.PortType;
import javax.wsdl.Service;
import javax.wsdl.WSDLException;

import org.eclipse.wst.wsdl.validation.internal.IValidationInfo;
import org.eclipse.wst.wsdl.validation.internal.IWSDLValidator;
import org.eclipse.wst.wsdl.validation.internal.ValidationInfoImpl;
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.wsdl11.WSDL11ValidationInfoImpl;
import org.eclipse.wst.wsdl.validation.internal.wsdl11.WSDLDocument;
import org.eclipse.wst.wsdl.validation.internal.wsdl11.WSDLReaderImpl;
import org.eclipse.wst.wsi.internal.WSIPreferences;
import org.eclipse.wst.wsi.internal.WSITestToolsProperties;
import org.eclipse.wst.wsi.internal.analyzer.WSDLAnalyzer;
import org.eclipse.wst.wsi.internal.analyzer.WSIAnalyzerException;
import org.eclipse.wst.wsi.internal.report.AssertionError;
import org.w3c.dom.Document;

/**
 * The WSI validator plugs into the WSDL validator to provide
 * validation for a WSDL document with respect to the WS-I Basic Profile (currently 1.0).
 * This class acts as an bridge between the WS-I tools and the WSDL Validator.
 * 
 * @author Lawrence Mandel (lmandel@ca.ibm.com)
 * @author Wajiha Rehman
 */
public class WSDLValidator implements IWSDLValidator
{
  protected final String WSI_PREFIX = "WS-I: ";
  protected final String _EXC_UNABLE_TO_VALIDATE_WSI = "_EXC_UNABLE_TO_VALIDATE_WSI";

  // indications for types of errors
  protected final int ERROR = 2;
  protected final int WARNING = 1;
  
  protected MessageGenerator messagegenerator = null;
  protected boolean wsiValid = false;

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

  /* (non-Javadoc)
   * @see org.eclipse.wsdl.validate.IWSDLValidator#validate(org.w3c.dom.Document, org.eclipse.wsdl.validate.ValidationInfo)
   */
  public void validate(Document domModel, IValidationInfo valInfo) throws ValidateWSDLException
  {
	boolean withAttachments = false;
	boolean withBasic = false;
	Object attValue = valInfo.getAttribute("http://ws-i.org/profiles/BasicWithAttachments/ComplianceLevel");
	if(attValue == null)
	{
	  attValue = valInfo.getAttribute("http://ws-i.org/profiles/Basic/ComplianceLevel");
   	  if(attValue != null)
	  {
	    withBasic = true;
	  }
	}
	else
	{
	  withAttachments = true;
	}
	String wsiLevel = WSITestToolsProperties.WARN_NON_WSI;
	if(attValue != null)
	{
	  String value = (String)attValue;
	  if(value.equals("IGNORE"))
	  {
	  	wsiLevel = WSITestToolsProperties.IGNORE_NON_WSI;
	  }
	  else if(value.equals("REQUIRE"))
	  {
	   	wsiLevel = WSITestToolsProperties.STOP_NON_WSI;
	  }
	}
	// If we are ignoring WS-I then don't run the tests.
	if(wsiLevel.equals(WSITestToolsProperties.IGNORE_NON_WSI))
	{
	  return;
	}
	    
  	wsiValid = true;
  	Definition definition = null;
	boolean hasAnalyzerConfig = false;
	String uri = valInfo.getFileURI();
  	try
  	{
      //WSDLFactory factory = WSDLFactory.newInstance();
 	  ValidationInfoImpl vali = new ValidationInfoImpl(valInfo.getFileURI(), messagegenerator);
  	  vali.setURIResolver((URIResolver)valInfo.getURIResolver());
      WSDLReaderImpl reader = new WSDLReaderImpl(new WSDL11ValidationInfoImpl(vali));
      WSDLDocument[] docs = reader.readWSDL(uri, domModel);
      int numdocs = docs.length;
      for(int i = 0; i < numdocs; i++)
      {
        WSDLDocument tempDoc = docs[i];
		if(tempDoc.getDefinition().getDocumentBaseURI().equals(valInfo.getFileURI()))
        {
          definition = tempDoc.getDefinition();  
          break;
        }
      }
  	}
  	catch(WSDLException e)
  	{
  	  throw new ValidateWSDLException(messagegenerator.getString(_EXC_UNABLE_TO_VALIDATE_WSI,uri));
  	}
	    
    if (definition != null && valInfo != null)
    {
      String namespace = definition.getTargetNamespace();

      // get all the collections we may need to validate
      Collection services = definition.getServices().values();
      Collection bindings = definition.getBindings().values();
      Collection portTypes = definition.getPortTypes().values();
      Collection messages = definition.getMessages().values();

      WSDLAnalyzer wsdlAnalyzer;
	  if(withAttachments)
	  {
	  	WSIPreferences preferences = new WSIPreferences();
   	    preferences.setComplianceLevel(wsiLevel);
	    preferences.setTADFile(WSITestToolsProperties.AP_ASSERTION_FILE);
	    wsdlAnalyzer = new WSDLAnalyzer(uri, preferences);
	  }
	  else if(withBasic)
	  {
	  	WSIPreferences preferences = new WSIPreferences();
		preferences.setComplianceLevel(wsiLevel);	
	    preferences.setTADFile(WSITestToolsProperties.SSBP_ASSERTION_FILE);
	    wsdlAnalyzer = new WSDLAnalyzer(uri, preferences);
	  }
	  else
	  {
		// default preference setting
	  	wsdlAnalyzer = new WSDLAnalyzer(uri);
	  }

	  // The WS-I conformance tools require that each service be analyzed separately.
	  // Get all the services and analyze them.
	  if (services != null && !services.isEmpty())
	  {
	    Iterator serviceIterator = services.iterator();

	    while (serviceIterator.hasNext())
        {
          Service service = (Service) serviceIterator.next();

          String servicename = service.getQName().getLocalPart();

          Collection ports = service.getPorts().values();
          if (ports != null && !ports.isEmpty())
          {
            // The WS-I tools must be called once for each port within each service.
            Iterator portIterator = ports.iterator();
            while (portIterator.hasNext())
            {
              Port port = (Port) portIterator.next();

              try
              {
                wsdlAnalyzer.addConfigurationToTest(servicename, namespace, port.getName(), WSDLAnalyzer.PORT);
				hasAnalyzerConfig = true;
              }
              catch (WSIAnalyzerException e)
              {
                // TODO: Add code to log error 
                //System.out.println("exception " + e);
              }

            }
          }
        }
      }
      // validate at the binding level - check for every binding
      else if (bindings != null && !bindings.isEmpty())
      {
        Iterator bindingIterator = bindings.iterator();

        while (bindingIterator.hasNext())
        {
          Binding binding = (Binding) bindingIterator.next();

          String bindingname = binding.getQName().getLocalPart();
          try
          {
            wsdlAnalyzer.addConfigurationToTest(null, namespace, bindingname, WSDLAnalyzer.BINDING);
			hasAnalyzerConfig = true;
          }
          catch (WSIAnalyzerException e)
          {
            // TODO: Add code to log error 
            //System.out.println("exception " + e);
          }
        }
      }
      // validate at the portType level - check for every portType
      else if (portTypes != null && !portTypes.isEmpty())
      {
        Iterator portTypeIterator = portTypes.iterator();
        while (portTypeIterator.hasNext())
        {
          PortType portType = (PortType) portTypeIterator.next();
          String portTypename = portType.getQName().getLocalPart();
          try
          {
            wsdlAnalyzer.addConfigurationToTest(null, namespace, portTypename, WSDLAnalyzer.PORTTYPE);
			hasAnalyzerConfig = true;
          }
          catch (WSIAnalyzerException e)
          {
            // TODO: Add code to log error 
            //System.out.println("exception " + e);
          }
        }
      }
      // validate at the message level - check for every message
      else if (messages != null && !messages.isEmpty())
      {
        Iterator messageIterator = messages.iterator();

        while (messageIterator.hasNext())
        {
          Message message = (Message) messageIterator.next();
          String messagename = message.getQName().getLocalPart();
          try
          {
            wsdlAnalyzer.addConfigurationToTest(null, namespace, messagename, WSDLAnalyzer.MESSAGE);
			hasAnalyzerConfig = true;
          }
          catch (WSIAnalyzerException e)
          {
            // TODO: Add code to log error 
            //System.out.println("exception " + e);
          }
        }
      }
      try
      {
        // only run the analyzer if there is something to check
		if(hasAnalyzerConfig)
		{
		  // run the conformance check and add errors and warnings as needed
		  wsdlAnalyzer.validateConformance();
			  
		  // If the level is suggest all errors should be reported as warnings.
		  if(wsdlAnalyzer.getWSIPreferences().getComplianceLevel().equals(WSITestToolsProperties.WARN_NON_WSI))
		  {
		    addWarnings(wsdlAnalyzer.getAssertionErrors(), valInfo);
		  }
		  else
		  {
		    addErrors(wsdlAnalyzer.getAssertionErrors(), valInfo);
		  }
		  addWarnings(wsdlAnalyzer.getAssertionWarnings(), valInfo);
		}
      }
	  catch (WSIAnalyzerException e)
	  {
		// TODO: Add code to log error 
		System.out.println("Unable to run WS-I WSDL conformance check.\n" + e);
	  }
    }
  }

  /**
   * Add error messages to the validationcontroller.
   * 
   * @param errors The list of errors to add.
   * @param valInfo The object that contains the validation information.
   */
  protected void addErrors(List errors, IValidationInfo valInfo)
  {
    reportProblems(errors, valInfo, ERROR);
  }

  /**
   * Add warning messages to the validationcontroller.
   * 
   * @param warnings The list of warnings to add.
   * @param valInfo The object that contains the validation information.
   */
  protected void addWarnings(List warnings, IValidationInfo valInfo)
  {
    reportProblems(warnings, valInfo, WARNING);
  }

  /**
   * Report the problems specified for the given type to the validationcontroller.
   * 
   * @param problems The problems to report.
   * @param valInfo The object to report the problems to.
   * @param type The type of messages to add.
   */
  protected void reportProblems(List problems, IValidationInfo valInfo, int type)
  {
    // if there were no problems just return
    if (problems == null)
      return;

    
    Iterator problemsIterator = problems.iterator();
    while (problemsIterator.hasNext())
    {
      AssertionError assertionerror = (AssertionError) problemsIterator.next();
      if (type == ERROR)
      {
		wsiValid = false;
        valInfo.addError(
          WSI_PREFIX + assertionerror.getErrorMessage(),
          assertionerror.getLine(),
          assertionerror.getColumn(),
          valInfo.getFileURI());

      }
      else if (type == WARNING)
      {
        valInfo.addWarning(
          WSI_PREFIX + assertionerror.getErrorMessage(),
          assertionerror.getLine(),
          assertionerror.getColumn(),
          valInfo.getFileURI());
      }
    }
  }

  /**
   * @see org.eclipse.wsdl.validate.controller.IWSDLValidator#setResourceBundle(java.util.ResourceBundle)
   */
  public void setResourceBundle(ResourceBundle rb)
  {
    messagegenerator = new MessageGenerator(rb);
  }

  /**
   * @see org.eclipse.wsdl.validate.controller.IWSDLValidator#isValid()
   */
  public boolean isValid()
  {
    return wsiValid;
  }

}
