/*******************************************************************************
 * 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.core.WSIConstants;
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 _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(
        		WSIConstants.WSI_PREFIX + "(" + assertionerror.getAssertionID()+ ") " + assertionerror.getErrorMessage(),
          assertionerror.getLine(),
          assertionerror.getColumn(),
          valInfo.getFileURI());

      }
      else if (type == WARNING)
      {
        valInfo.addWarning(
        		WSIConstants.WSI_PREFIX + "(" + assertionerror.getAssertionID()+ ") " + 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;
  }

}
