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

import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.wsdl.Definition;
import javax.wsdl.Import;
import javax.wsdl.WSDLException;

import org.apache.xerces.xni.grammars.XMLGrammarPool;
import org.apache.xerces.xs.XSModel;
import org.eclipse.wst.wsdl.validation.internal.IValidationMessage;
import org.eclipse.wst.wsdl.validation.internal.resolver.IURIResolutionResult;
import org.eclipse.wst.wsdl.validation.internal.util.ErrorMessage;
import org.eclipse.wst.wsdl.validation.internal.util.MessageGenerator;
import org.eclipse.wst.wsdl.validation.internal.wsdl11.xsd.XSDValidator;
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.XMLCatalogResolver;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;

import com.ibm.wsdl.Constants;
import com.ibm.wsdl.util.StringUtils;
import com.ibm.wsdl.util.xml.DOMUtils;
import com.ibm.wsdl.util.xml.QNameUtils;

/**
 * A class to hold and parse an import element.
 */
public class ImportHolder implements Comparable
{
  private MessageGenerator messagegenerator;
  
  private WSDLDocument importingWSDLDoc = null;
  private WSDLDocument wsdlDocument = null;
  private Definition importingDef = null;
  private Element importingDocImportElement = null;
  private String namespace = null;
  private String location = null;
  private String classpathURI = null;
  private String contextURI = null;
  private int depth;
  private Element element = null;
  private List schemas = new ArrayList();
  private boolean isWSDLFileImport = true;
  private boolean importInvalid = false;
  private Import importDef = null;
  private IWSDL11ValidationInfo valinfo;
  
  /**
   * Constructor.
   * 
   * @param namespace The namespace of the import.
   * @param location The location of the import.
   * @param contextURI The context URI for resolving the import location.
   * @param wsdlDoc The WSDLDocument that contains the import.
   * @param depth The depth of the import.
   * @param importingDocImportElement The element representing the import in the encapsulating WSDLDocument.
   * @param messagegenerator A messagegenerator for obtaining strings.
   * @param valinfo The WSDL11ValidationInfo for reporting messages.
   */
  public ImportHolder(String namespace, String location, String contextURI, WSDLDocument importingWSDLDoc, int depth, Element importingDocImportElement, MessageGenerator messagegenerator, IWSDL11ValidationInfo valinfo)
  {
    this.messagegenerator = messagegenerator;
    this.valinfo = valinfo;
    this.importingWSDLDoc = importingWSDLDoc;
    if(importingWSDLDoc != null)
    {
      this.importingDef = importingWSDLDoc.getDefinition();
    }
    this.importingDocImportElement = importingDocImportElement;
    this.depth = depth;
    this.namespace = namespace;
    this.location = location;
    
    //  Allow WSDL imports to have no location attribute even though it is required.
    // Schema will normally catch the problem but this allows users to override the
    // schema and have the validator run.
    if (this.location == null)
    {
      this.location = namespace;
    }
    this.contextURI = contextURI;
    
    this.location = this.location.replace('\\','/');
    IURIResolutionResult classpathURI = valinfo.getURIResolver().resolve(this.contextURI, this.namespace, this.location);
    if(classpathURI.getLogicalLocation() != null)
    {
      this.location = classpathURI.getLogicalLocation();
    }
    if(classpathURI.getPhysicalLocation() != null)
    {
      this.classpathURI = classpathURI.getPhysicalLocation();
      this.contextURI = null;
    } 
  }
  
  public void initialize()
  {
    Element documentElement = null;
    try
    {
      documentElement = getElement();
    }
    catch(WSDLException e)
    {
    }
    if(documentElement != null)
    {
  	  // Handle WSDL imports.
      if (QNameUtils.matches(Constants.Q_ELEM_DEFINITIONS, documentElement))
      {
        if(isXMLValid(this.classpathURI))
        {
          try
          {
            wsdlDocument = new WSDLDocument(this.location, documentElement, this.depth, this.messagegenerator, this.valinfo);
            createWSDLImport(wsdlDocument);
          }
          catch(WSDLException e)
          {
            valinfo.addError(messagegenerator.getString("_UNABLE_TO_IMPORT_BAD_LOCATION", "'" + importDef.getLocationURI() + "'"), importingDocImportElement);
          }
        }
      }
      // Handle schema imports.
      else if (QNameUtils.matches(Constants.Q_ELEM_XSD_2001, documentElement))
      {
        createXSDImport();
      }
    }
  }
  
  protected boolean isXMLValid(String uri)
  {
    IXMLValidator xmlValidator = AbstractXMLConformanceFactory.getInstance().getXMLValidator();
    xmlValidator.setFile(uri);
    xmlValidator.setURIResolver(valinfo.getURIResolver());
    //xmlValidator.setValidationInfo(valInfo);
    if(xmlValidator instanceof DefaultXMLValidator)
    {
    	XMLGrammarPool grammarPool = valinfo.getXMLCache();
        if(grammarPool != null)
          ((DefaultXMLValidator)xmlValidator).setGrammarPool(grammarPool);
    }
    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();
        valinfo.addError(valMes.getMessage(), valMes.getLine(), valMes.getColumn(), valMes.getURI());
      }
      importInvalid = true;
      return false;
    }
    return true;
  }
  
  /**
   * Get the importing WSDLDocument.
   * 
   * @return The importing WSDLDocument.
   */
  public WSDLDocument getImportingDocument()
  {
    return importingWSDLDoc;
  }
  
  /**
   * Get the WSDL document this import represents.
   * 
   * @return The WSDL document this import represents.
   */
  public WSDLDocument getWSDLDocument()
  {
    return wsdlDocument;
  }
  
  /**
   * Get the namespace.
   * 
   * @return The namespace.
   */
  public String getNamespace()
  {
    return namespace;
  }
  
  /**
   * Get the location.
   * 
   * @return The location.
   */
  public String getLocation()
  {
    return location;
  }
  
  /**
   * Get the context URI.
   * 
   * @return The context URI.
   */
  public String getContextURI()
  {
    return contextURI;
  }
  
  /**
   * Get the depth in the WSDL tree.
   * 
   * @return The depth in the WSDL tree.
   */
  public int getDepth()
  {
    return depth;
  }
  
  /**
   * Get the containing defintions element.
   * 
   * @return The containing definitions element.
   */
  public Definition getImportingDefinition()
  {
    return importingDef;
  }
  
  /**
   * Get the element for this import.
   * 
   * @return The element for this import.
   * @throws WSDLException
   */
  public Element getElement() throws WSDLException
  {
    if(element != null)
    {
      return element;
    }
    
    String locationURI = location;
    //Import importDef = importingDef.createImport();
    
    //  Allow locating WSDL documents using any registered URI resolver.
    //String classpathURI = URIResolver.getInstance().resolve(contextURI, namespaceURI, locationURI);
//    if (!classpathURI.equals(locationURI))
//    {
//      locationURI = classpathURI;
//      contextURI = null;
//    }
    Reader reader = null;
    if (locationURI != null)
    {
        try
        {
          //String contextURI = def.getDocumentBaseURI();
          //Definition importedDef = null;
          
          InputSource inputSource = null;
          URL url = null;

          
            URL contextURL = (contextURI != null) ? StringUtils.getURL(null, contextURI) : null;

            url = StringUtils.getURL(contextURL, locationURI);
            
            // Handle file:// urls. The correct format should be file:/// or file:/.
            String urlAuthority = url.getAuthority();
            String urlProtocol = url.getProtocol();
            if(urlAuthority !=null && urlProtocol.equalsIgnoreCase("file") && !urlAuthority.equals(""))
             {
              url = new URL(urlProtocol,"","/" + urlAuthority + url.getFile());
            }
            
            String urlString = url.toString();
			// Test for case sensitivity on local files.
			if(urlString.startsWith("file:"))
			{
			  File testfile = new File(url.getFile());
			  String testfileString = testfile.getAbsolutePath();
			  String canonicalfileString = testfile.getCanonicalPath();

              if (!testfileString.equals(canonicalfileString))
              {
				if (!String.valueOf(testfileString.charAt(0)).equalsIgnoreCase
				    (String.valueOf(canonicalfileString.charAt(0)))
				    || !testfileString.substring(1,testfileString.length()).equals
					(canonicalfileString.substring(1,canonicalfileString.length())))
				{
                  urlString = "";
                  url = null;
				}
              }
			}
			if(url != null)
			{
			  try
			  {
                reader = StringUtils.getContentAsReader(url);
			  }
			  catch(IOException e)
			  {
			    // No need to do anything here. The error will be handled below.
			  }
			}
            if (reader != null)
            {
              inputSource = new InputSource(reader);
              if(classpathURI != null && !classpathURI.equals(location))
  			  {
  			    inputSource.setByteStream(new URL(classpathURI).openStream());
  			  }
            }

            if (inputSource == null)
            {
              // Get the actual location from the element.
              String actualLocation = DOMUtils.getAttribute(importingDocImportElement, Constants.ATTR_LOCATION);
              if(actualLocation == null)
              {
              	actualLocation = DOMUtils.getAttribute(importingDocImportElement, "schemaLocation");
              }
              if(actualLocation == null)
              {
              	actualLocation = namespace;
              }
              importingWSDLDoc.addReaderWarning(
                  importingDef,
                  importingDocImportElement,
                  messagegenerator.getString("_UNABLE_TO_IMPORT_BAD_LOCATION", "'" + actualLocation + "'"));
              importInvalid = true;
               
              // TODO: modify the reader error to show in all the correct locations.
              throw new WSDLException(
                WSDLException.OTHER_ERROR,
                "Unable to locate imported document "
                  + "at '"
                  + locationURI
                  + "'"
                  + (contextURI == null ? "." : ", relative to '" + contextURI + "'."));
            }
            Document doc = null;
            try
            {
              doc = WSDLReaderImpl.getDocument(inputSource, locationURI);
            }
            catch(WSDLException e)
            {
              // The File is invalid and cannot be read. 
              // Perform XML validation.
              isXMLValid(locationURI);
//              importingWSDLDoc.addReaderError(
//                  importingDef,
//                  importingDocImportElement,
//                  messagegenerator.getString("_UNABLE_TO_IMPORT_INVALID", "'" + location + "'"));
              throw e;
            }
            element = doc.getDocumentElement();
            if(!QNameUtils.matches(Constants.Q_ELEM_DEFINITIONS, element))
            {
              isWSDLFileImport = false;
            }
            // Ensure that the imported document has the same namespace as the import element states.
            String importTargetNS = element.getAttribute(Constants.ATTR_TARGET_NAMESPACE);
            if(!importTargetNS.equals(namespace))
            {
              importingWSDLDoc.addReaderWarning(
                  importingDef,
                  importingDocImportElement,
                  messagegenerator.getString("_WARN_WRONG_NS_ON_IMPORT", "'" + namespace + "'", "'" + importTargetNS + "'"));
              element = null;
              importInvalid = true;
            }
          }
        
        catch(Exception e)
        {
        }
        finally
        {
          if(reader != null)
          {
            try
            {
              reader.close();
            }
            catch(IOException e)
            {}
          }
        }
      
    }
    return element;
  }
  
  /**
   * Create an import element for a WSDL import of a WSDL document.
   * 
   * @param wsdlDocument The document of the import.
   * @return The newly created import element.
   */
  public Import createWSDLImport(WSDLDocument wsdlDocument)
  {
    if(importDef != null)
    {
      return importDef;
    }
    importDef = getNewImport();
  
    if (importDef != null)
    {
      importDef.setDefinition(wsdlDocument.getDefinition());
      schemas.addAll(wsdlDocument.getSchemas());
      importingWSDLDoc.addSchemas(schemas);
    }

    return importDef;
  }
  
  /**
   * Create an import element for a WSDL import of a schema import of a schema document.
   * 
   * @return The newly created import element.
   */
  public Import createXSDImport()
  {
    if(importDef != null)
    {
      return importDef;
    }
    importDef = getNewImport();
    XSDValidator xsdvalidator = new XSDValidator();

    xsdvalidator.validate(location, XMLCatalogResolver.getInstance(), valinfo.getSchemaCache());
    if (xsdvalidator.isValid())
    {
      XSModel schema = xsdvalidator.getXSModel();
      if (schema != null)
      {
        schemas.add(schema);
      }
    }
    else
    {
     // addReaderWarning(
//        def,
//        importDef,
//        messagegenerator.getString("_UNABLE_TO_IMPORT_INVALID", "'" + importDef.getLocationURI() + "'"));
      Iterator errors = xsdvalidator.getErrors().iterator();
      while (errors.hasNext())
      {
        ErrorMessage err = (ErrorMessage) errors.next();
        String uri = err.getURI();
        int line = err.getErrorLine();
        String errmess = err.getErrorMessage();
        valinfo.addError(errmess, line, err.getErrorColumn(), uri);
      }
    }
    importingWSDLDoc.addSchemas(schemas);
    return importDef;
  }
  
  /**
   * Get the import element if it has been created.
   * 
   * @return The import element if it has been created or null.
   */
  public Import getImport()
  {
    return importDef;
  }
  
  /**
   * Get a new import element.
   * 
   * @return A new import element.
   */
  private Import getNewImport()
  {
    if(importInvalid)
    {
      return null;
    }
    Import importDef = importingDef.createImport(); 
    
    if (namespace != null)
    {
      importDef.setNamespaceURI(namespace);
    }

    if (location != null)
    {
      importDef.setLocationURI(location);
    }
    
    if(element != null)
    {
      Element tempEl = DOMUtils.getFirstChildElement(element);

      while (tempEl != null)
      {
        if (QNameUtils.matches(Constants.Q_ELEM_DOCUMENTATION, tempEl))
        {
          importDef.setDocumentationElement(tempEl);
        }

        tempEl = DOMUtils.getNextSiblingElement(tempEl);
      }
    }

    return importDef;
  }
  
  /**
   * Get the schemas corresponding to this import.
   * 
   * @return The schemas corresponding to this import.
   */
  public List getSchemas()
  {
    return schemas;
  }
  
  /**
   * Returns true if this import imports a WSDL document, false otherwise.
   * 
   * @return True if this import imports a WSDL document, false otherwise.
   */
  public boolean isWSDLFileImport()
  {
    return isWSDLFileImport;
  }
  
  /* (non-Javadoc)
   * @see java.lang.Object#equals(java.lang.Object)
   */
  public boolean equals(Object obj)
  {
    if(obj.getClass() == ImportHolder.class)
    {
      ImportHolder otherImport = (ImportHolder)obj;
      
      if(getNamespace().equals(otherImport.getNamespace()) && getLocation().equals(otherImport.getLocation()))
      {
        return true;
      }
    }
    return false;
  }
  
  /* (non-Javadoc)
   * @see java.lang.Comparable#compareTo(java.lang.Object)
   */
  public int compareTo(Object obj)
  {
    if(obj == null)
    {
      throw new NullPointerException();
    }
    
    ImportHolder otherImport = (ImportHolder)obj;
      
    return (getNamespace()+getLocation()).compareTo((otherImport.getNamespace()+otherImport.getLocation()));
  }
  
  /**
   * Set the messagegenerator for the import holder.
   * 
   * @param mg The message generator to set.
   */
  public void setMessageGenerator(MessageGenerator mg)
  {
    messagegenerator = mg;
  }
  
  /**
   * Return true if the import is invalid, false otherwise.
   * 
   * @return True if the import is invalid, false otherwise.
   */
  public boolean isImportInvalid()
  {
    return importInvalid;
  }
}