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

import java.io.File;

import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.DTDLocation;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.XMLCatalog;
import org.eclipse.wst.wsdl.validation.internal.IValidationMessage;
import org.eclipse.wst.wsdl.validation.internal.IValidationReport;
import org.eclipse.wst.wsdl.validation.internal.WSDLValidator;
import org.eclipse.wst.wsdl.validation.internal.WSDLValidatorDelegate;
import org.eclipse.wst.wsdl.validation.internal.resolver.URIResolverDelegate;
import org.eclipse.wst.wsdl.validation.internal.util.MessageGenerator;
import org.eclipse.wst.wsdl.validation.internal.wsdl11.WSDL11ValidatorDelegate;

/**
 * An Ant task to run WSDL validation on a file or a set of files.
 * 
 * Options
 * - file - the file to run validation on (optional if fileset is used)
 * - failonerror - fail the build process on the first file with an error
 * - wsicompliance - how to report WS-I errors - REQUIRE, SUGGEST, IGNORE (defaults to REQUIRE)
 * 
 * Supported Nested Elements
 * - xmlcatalog - an xml catalog
 * - dtd        - a dtd specification as would appear in an xmlcatalog
 * - schema     - a schema specification as would appear in an xmlcatalog
 * - entity     - an entity specification as would appear in an xmlcatalog
 * - fileset    - a set of files to validate
 * - wsdl11validator - an extension WSDL 1.1 validator
 * - uriresolver - an extension URI resolver
 * 
 */
public class WSDLValidate extends Task
{
  protected final String UI_PROPERTIES = "validatewsdlui";
  protected final String VALIDATOR_PROPERTIES = org.eclipse.wst.wsdl.validation.internal.Constants.WSDL_VALIDATOR_PROPERTIES_FILE;
  protected final String _ERROR_NO_FILE_SPECIFIED = "_ERROR_NO_FILE_SPECIFIED";
  protected final String _UI_INFORMATION_DELIMITER = "_UI_INFORMATION_DELIMITER";
  protected final String _UI_ACTION_VALIDATING_FILE = "_UI_ACTION_VALIDATING_FILE";
  protected final String _UI_ERROR_MARKER = "_UI_ERROR_MARKER";
  protected final String _UI_WARNING_MARKER = "_UI_WARNING_MARKER";
  protected final String _UI_VALID = "_UI_VALID";
  protected final String _UI_INVALID = "_UI_INVALID";
  protected final String _EXC_UNABLE_TO_VALIDATE_FILE = "_EXC_UNABLE_TO_VALIDATE_FILE";
  protected final String _EXC_WSDL_FAIL_ON_ERROR = "_EXC_WSDL_FAIL_ON_ERROR";
  
  protected final String FILE_PROTOCOL = "file:///";

  // Global Vars
  protected List filesets = new ArrayList();
  protected String file = null;
  protected Path classpath;
  protected String xsdDirectory = null;
  protected boolean failOnError = false;
  protected XMLCatalog globalXMLCatalog = new XMLCatalog();
  protected List wsdl11validators = new ArrayList();
  protected List extvalidators = new ArrayList();
  protected List extURIResolvers = new ArrayList();

  /**
   * Constuctor.
   */
  public WSDLValidate()
  {
  }

  /**
   * Tells the WSDL validate task to fail the build if an error is encountered.
   * 
   * @param failOnError Whether to fail on error or not.
   */
  public void setFailOnError(boolean failOnError)
  {
    this.failOnError = failOnError;
  }

  /**
   * Set the directory where the base schema files for the catalog are located.
   * 
   * @param dir - the directory of the base schema files
   */
  public void setSchemaDir(String dir)
  {
    xsdDirectory = dir;
  }

  /**
   * Set a file to run WSDL validation on.
   * 
   * @param file - a file to run validation on
   */
  public void setFile(String file)
  {
    this.file = file;
  }

  /**
   * Create a set of files to run WSDL validation on.
   * 
   * @return the FileSet of files to run WSDL validation on
   */
  public FileSet createFileset()
  {
    FileSet fileset = new FileSet();
    filesets.add(fileset);
    return fileset;
  }

  /**
   * Add an XML catalog to the validator.
   * 
   * @param catalog - the catalog to add to the validator
   */
  public void addConfiguredXMLCatalog(XMLCatalog catalog)
  {
    globalXMLCatalog.addConfiguredXMLCatalog(catalog);
  }
  /**
   * Add an extension validator.
   * 
   * @param extVal The extension validator to add.
   */
  public void addConfiguredExtensionValidator(ExtensionValidator extVal)
  {
    extvalidators.add(extVal);
  }
  /**
   * Add an extension WSDL 1.1 validator.
   * 
   * @param extVal The extension WSDL 1.1 validator to add.
   */
  public void addConfiguredWSDL11Validator(ExtensionValidator extVal)
  {
    wsdl11validators.add(extVal);
  }

  /**
   * Allow specification of an entity outside of an XMLCatalog.
   * 
   * @return a DTDLocation with the specified entity
   **/
  public DTDLocation createEntity()
  {
    DTDLocation dtdLoc = new DTDLocation();
    globalXMLCatalog.addEntity(dtdLoc);
    return dtdLoc;
  }

  /**
   * Allow specification of a DTD outside of an XMLCatalog.
   * 
   * @return a DTDLocation with the specified DTD
   **/
  public DTDLocation createDTD()
  {
    DTDLocation dtdLoc = new DTDLocation();
    globalXMLCatalog.addEntity(dtdLoc);
    return dtdLoc;
  }
  
  /**
   * Create a URIResolver extension.
   * 
   * @return A URIResolver.
   */
  public URIResolver createURIResolver()
  {
    URIResolver urires = new URIResolver();
    extURIResolvers.add(urires.getClassName());
    return urires;
    
  }

  /**
   * Get a list of all the files to run WSDL validation on. Takes the file and fileset
   * and creates the list.
   * 
   * @return the list of files to be validated
   */
  protected List getFileList()
  {
    List files = new ArrayList();

    // if a specific file was specified add it to the list
    if (file != null)
    {
      try
      {
        URL url = new URL(file);
        files.add(url.toExternalForm());
      }
      catch(Exception e)
      {
        File theFile = new File(file);
        if(!theFile.isAbsolute())
        {
          theFile = new File(getProject().getBaseDir(), file);
        }
        String absFile = theFile.toString(); 
        if(!absFile.startsWith("file:"))
        {
          absFile = FILE_PROTOCOL + absFile;
        }
        absFile = absFile.replace('\\','/');
        files.add(absFile);
      }
    }

    // go through all filesets specified and add all the files to the list
    Iterator fsIter = filesets.iterator();
    while (fsIter.hasNext())
    {
      FileSet fileset = (FileSet)fsIter.next();
      DirectoryScanner ds = fileset.getDirectoryScanner(fileset.getProject());
      String basedir = ds.getBasedir().toString() + File.separator;

      String[] filelist = ds.getIncludedFiles();
      int numFiles = filelist.length;
      if (files != null && numFiles > 0)
      {
        for (int i = 0; i < numFiles; i++)
        {
          String absFile = FILE_PROTOCOL + basedir + filelist[i];
          absFile = absFile.replace('\\','/');
          files.add(absFile);
        }
      }
    }
    return files;
  }

  /* (non-Javadoc)
   * @see org.apache.tools.ant.Task#execute()
   */
  public void execute() throws BuildException
  {
    // the resource bundles for the ui and validator are needed
    MessageGenerator messGen = null;
    try
    {
      ResourceBundle uiRB = ResourceBundle.getBundle(UI_PROPERTIES);
      messGen = new MessageGenerator(uiRB);
    }
    catch (MissingResourceException e)
    {
      // if the resource bundles can't be opened we can't report error so throw an exception
      throw new BuildException("Unable to open resource bundle. " + e);
    }

    // Set the XML catalog.
    org.eclipse.wst.wsdl.validation.internal.xml.XMLCatalog.setExtensionXMLCatalog(XMLCatalogImpl.class.getName(), getClass().getClassLoader());
    XMLCatalogImpl xmlCatalog = (XMLCatalogImpl)org.eclipse.wst.wsdl.validation.internal.xml.XMLCatalog.getExtensionCatalogInstance();
    xmlCatalog.addXMLCatalog(globalXMLCatalog);
    
    WSDLValidator wsdlValidator = new WSDLValidator();
    
    // Set the extension URIResolvers.
    Iterator resolversIter = extURIResolvers.iterator();
    while(resolversIter.hasNext())
    {
      String resolverClass = (String)resolversIter.next();
      wsdlValidator.addURIResolver(new URIResolverDelegate(resolverClass, getClass().getClassLoader()).getURIResolver());
    }
    
    // Get the list of files to validate.
    List files = getFileList();
    
    // Register the WSDL 1.1 extension validators.
    Iterator wsdl11extIter = wsdl11validators.iterator();
    while(wsdl11extIter.hasNext())
    {
      ExtensionValidator extVal = (ExtensionValidator)wsdl11extIter.next();
      WSDL11ValidatorDelegate delegate = new WSDL11ValidatorDelegate(extVal.getClassName(), extVal.getResourceBundle());
      wsdlValidator.registerWSDL11Validator(extVal.getNamespace(), delegate);
    }
    
    // Register the extension validators.
    Iterator extIter = extvalidators.iterator();
    while(extIter.hasNext())
    {
      ExtensionValidator extVal = (ExtensionValidator)extIter.next();
      WSDLValidatorDelegate delegate = new WSDLValidatorDelegate(extVal.getClassName(), extVal.getResourceBundle());
      wsdlValidator.registerWSDLExtensionValidator(extVal.getNamespace(), delegate);
    }

    // The user didn't specify any files to validate.
    if (files == null || files.isEmpty())
    {
      System.err.println(messGen.getString(_ERROR_NO_FILE_SPECIFIED));
      return;
    }

    if (xsdDirectory != null)
    {
      org.eclipse.wst.wsdl.validation.internal.xml.XMLCatalog.addSchemaDir(xsdDirectory);
    }

    // Validate all the files specified.
    Iterator iFiles = files.iterator();

    // Common strings needed in validation output.
    String infoDelim = messGen.getString(_UI_INFORMATION_DELIMITER);
    String valid = messGen.getString(_UI_VALID);
    String invalid = messGen.getString(_UI_INVALID);
    String errormarker = messGen.getString(_UI_ERROR_MARKER);
    String warningmarker = messGen.getString(_UI_WARNING_MARKER);

    StringBuffer result = null;
    boolean notvalid = true;
    while (iFiles.hasNext())
    {
      result = new StringBuffer();
      notvalid = false;
      String filename = (String)iFiles.next();
      try
      {
        result.append(infoDelim).append("\n");
        result.append(messGen.getString(_UI_ACTION_VALIDATING_FILE, filename)).append(" - ");

        IValidationReport valReport = wsdlValidator.validate(filename);

        IValidationMessage[] messages = valReport.getValidationMessages();

        if (!valReport.hasErrors())
        {
          result.append(valid);
        }
        else
        {
          result.append(invalid);
          notvalid = true;
        }
        result.append("\n").append(infoDelim).append("\n");

        result.append(reportMessages(messages, errormarker, warningmarker));

        System.out.println(result.toString());
      }
      catch (Exception e)
      {
        System.err.println(messGen.getString(_EXC_UNABLE_TO_VALIDATE_FILE, filename, e));
      }
      finally
      {
        if (notvalid && failOnError)
        {
          // To fail on error, throw a build exception.
          throw new BuildException(messGen.getString(_EXC_WSDL_FAIL_ON_ERROR));
        }
      }
    }

    org.eclipse.wst.wsdl.validation.internal.xml.XMLCatalog.reset();

  }

  /**
   * Return a string with formatted output for the messages.
   * 
   * @param messages The messages to report.
   * @param errormarker The marker to use for error messages.
   * @param warningmarker The marker to use for warning messages.
   * @return A string with the formatted output.
   */
  protected String reportMessages(IValidationMessage[] messages, String errormarker, String warningmarker)
  {
    StringBuffer returnBuffer = new StringBuffer();

    if (messages == null)
      return returnBuffer.toString();

    String prefix = null;
    int numMessages = messages.length;
    for(int i = 0; i < numMessages; i++)
    {
      IValidationMessage message = messages[i];

      if(message.getSeverity() == IValidationMessage.SEV_ERROR)
       {
        prefix = errormarker;
      }
      else if(message.getSeverity() == IValidationMessage.SEV_WARNING)
       {
        prefix = warningmarker;
      }
      else
       {
        prefix = "";
      }if(message.getSeverity() == IValidationMessage.SEV_ERROR)
       {
        prefix = errormarker;
      }
      else if(message.getSeverity() == IValidationMessage.SEV_WARNING)
       {
        prefix = warningmarker;
      }
      else
       {
        prefix = "";
      }if(message.getSeverity() == IValidationMessage.SEV_ERROR)
       {
        prefix = errormarker;
      }
      else if(message.getSeverity() == IValidationMessage.SEV_WARNING)
       {
        prefix = warningmarker;
      }
      else
       {
        prefix = "";
      }if(message.getSeverity() == IValidationMessage.SEV_ERROR)
       {
        prefix = errormarker;
      }
      else if(message.getSeverity() == IValidationMessage.SEV_WARNING)
       {
        prefix = warningmarker;
      }
      else
       {
        prefix = "";
      }
      returnBuffer
        .append(prefix)
        .append(" ")
        .append(message.getLine())
        .append(":")
        .append(message.getColumn())
        .append(":")
        .append(message.getMessage())
        .append("\n");
    }
    return returnBuffer.toString();
  }
}