/**
 * Copyright (c) 2002-2007 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 * 
 * Contributors: 
 *   IBM - Initial API and implementation
 */
package org.eclipse.xsd.util;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;

import org.eclipse.xsd.XSDElementDeclaration;
import org.eclipse.xsd.XSDImport;
import org.eclipse.xsd.XSDInclude;
import org.eclipse.xsd.XSDRedefine;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.XSDSchemaContent;
import org.eclipse.xsd.XSDSchemaDirective;
import org.eclipse.xsd.XSDTypeDefinition;


// Various Eclipse, etools and EMF dependencies

// xsd:annotation elements are modeled in the DOM



/**
 * XSDSchemaQueryTools is a collection of worker methods for performing 
 * simple queries or searches of schemas.
 *
 * <p>These are suitable to show examples of how to build convenience 
 * methods to more easily find components in a schema.  They also 
 * serve as useful examples of usage of the library's functions.</p>
 *
 * <p>Note that these methods are somewhat simplistic, especially 
 * in terms of support for namespaces.  To simplify the calling 
 * signatures, and to account for the 80% case where you don't have 
 * multiple namespaces, most method simply take a localName that's 
 * assumed to be correct in the current context.  However it should 
 * be simple to copy & paste these methods and add namespaceURI's to 
 * each method if desired.</p>
 *
 * @author Shane_Curcuru@us.ibm.com
 */
public abstract class XSDSchemaQueryTools
{
  /**
   * Find typeDefinitions that derive from a named type. 
   *
   * <p>This shows one way to query the schema for typeDefinitions 
   * and then how to find specific kinds of typeDefinitions.</p>
   *
   * @param schema to search for typeDefs
   * @param namespace for the type derived from
   * @param localName for the type derived from
   * @return List of any XSDTypeDefinitions found
   */
  public static List<XSDTypeDefinition> findTypesDerivedFrom(XSDSchema schema, String namespace, String localName)
  {
    if ((null == schema) || (null == localName))
    {
      throw new IllegalArgumentException("findTypesDerivedFrom called with null schema/localName");
    }

    ArrayList<XSDTypeDefinition> typesDerivedFrom = new ArrayList<XSDTypeDefinition>();

    // A handy convenience method quickly gets all 
    // typeDefinitions within our schema; note that 
    // whether or not this returns types in included, 
    // imported, or redefined schemas is subject to change
    List<XSDTypeDefinition> typedefs = schema.getTypeDefinitions();

    for (XSDTypeDefinition typedef : typedefs)
    {
      // Walk the baseTypes from this typedef seeing if any 
      // of them match the requested one
      if (isTypeDerivedFrom(typedef, namespace, localName))
      {
        // We found it, return the original one and continue
        typesDerivedFrom.add(typedef);
        continue;
      }
    }

    return typesDerivedFrom;
  }

  /**
   * Recursive worker method to find typeDefinitions that derive 
   * from a named type. 
   *
   * <p>This is not a terribly time-efficient algorithm, but 
   * it does show usage of library methods. This works for 
   * simpleTypes; complexType support needs to be added.</p>
   *
   * @see #findTypesDerivedFrom(XSDSchema, String, String)
   * @param typedef to see if it's derived from
   * @param namespace for the type derived from
   * @param localName for the type derived from
   * @return true if it is; false otherwise
   * @deprecated Use {@link XSDConstants#isOrIsDerivedFrom(XSDTypeDefinition, String, String)} instead.
   */
  @Deprecated
  public static boolean isTypeDerivedFrom(XSDTypeDefinition typedef, String namespace, String localName)
  {
    return XSDConstants.isOrIsDerivedFrom(typedef, localName, namespace);
  }

  /**
   * Find elementDeclarations that use any types derived 
   * from a named type. 
   *
   * <p>This shows one way to query the schema for elementDeclarations 
   * and then how to find specific kinds of typeDefinitions.</p>
   *
   * @param schema to search for elemDecls
   * @param namespace for the type used
   * @param localName for the type used
   * @return List of any XSDElementDeclarations found
   */
  public static List<XSDElementDeclaration> findElementsUsingType(XSDSchema schema, String namespace, String localName)
  {
    if ((null == schema) || (null == localName))
    {
      throw new IllegalArgumentException("findElementsUsingType called with null schema/localName");
    }

    ArrayList<XSDElementDeclaration> elemsUsingType = new ArrayList<XSDElementDeclaration>();

    // A handy convenience method quickly gets all 
    // elementDeclarations within our schema; note that 
    // whether or not this returns types in included, 
    // imported, or redefined schemas is subject to change
    List<XSDElementDeclaration> elemDecls = schema.getElementDeclarations();

    for (XSDElementDeclaration elem : elemDecls)
    {
      XSDTypeDefinition typedef = null;
      if (elem.getAnonymousTypeDefinition() != null)
      {
        typedef = elem.getAnonymousTypeDefinition();
      }
      else if (elem.getTypeDefinition() != null)
      {
        typedef = elem.getTypeDefinition();
      }
      else
      {
        // Element is not complete, since it has no type, 
        // thus it's not using our type
        continue;
      }

      // Ask this type and walk the baseTypes from this 
      // typedef seeing if any of them match the requested one
      if (typedef.hasNameAndTargetNamespace(localName, namespace)
        || isTypeDerivedFrom(typedef, namespace, localName))
      {
        // We found it, return the element and continue
        elemsUsingType.add(elem);
        continue;
      }
    }

    return elemsUsingType;
  }

  /**
   * Find any included, imported, or redefined schemas that 
   * this one references. 
   *
   * <p>This method uses solely the Schema model API to look for 
   * XSDSchemaDirective objects. Each directive is the result 
   * of an include, import, or redefine in our schema. We then 
   * walk the tree of directives, finding their resolved schemas 
   * (if available), and produce a simple HashMap of them all.</p>
   * <p>See also {@link #hasImpInclRedef2(XSDSchema)}
   * which uses the underlying ResourceSet model to query the 
   * external resources that were loaded with this schema: it 
   * has the same effect, but using different code.</p>
   * 
   * @see #hasImpInclRedef2(XSDSchema)
   * @param schema object to search for imports/includes/redefines
   * @return HashMap where keys are the URI's of any other schemas 
   * found, and values are one of 'import', 'include', 'redefine';
   * null if none found or an error occurred
   */
  public static HashMap<String, String> hasImpInclRedef(XSDSchema schema)
  {
    if (null == schema)
    {
      throw new IllegalArgumentException("hasImpInclRedef called with null schema");
    }
    HashMap<String, String> hash = new HashMap<String, String>();

    // Recurse to map all imports/includes/redefines
    mapImpInclRedef(schema, hash, 0);

    // If none were found, return null
    if (hash.size() == 0)
    {
      return null;
    }
    return hash;
  }

  /**
   * Find any included, imported, or redefined schemas that 
   * this one references. 
   *
   * <p>This method uses the underlying ResourceSet model to query the 
   * external resources that were loaded with this schema. 
   * Note that the ResourceSet implementation is subject to change.</p>
   * 
   * @see #hasImpInclRedef(XSDSchema)
   * @param schema object to search for imports/includes/redefines
   * @return HashMap where keys are the URI's of any other schemas 
   * found, and values are one of 'import', 'include', 'redefine';
   * null if none found or an error occurred
   */
  public static HashMap<String, String> hasImpInclRedef2(XSDSchema schema)
  {
    if (null == schema)
    {
      throw new IllegalArgumentException("hasImpInclRedef2 called with null schema");
    }
    HashMap<String, String> hash = new HashMap<String, String>();

    // Use the Resource framework to iterate through any 
    // other resources that were loaded along with this schema 
    // to find what they import/include/redefine
    Resource currentResource = schema.eResource();

    // Get the whole set of resources that were loaded together
    ResourceSet resourceSet = currentResource.getResourceSet();

    // Iterate over all the resources, i.e., the main resource 
    // and those that have been included, imported, or redefined.
    for (Resource resource : resourceSet.getResources())
    {
      // Check for schema resources.
      if (resource instanceof XSDResourceImpl)
      {
        XSDResourceImpl xsdResource = (XSDResourceImpl)resource;

        // Iterate over each schema's content looking for directives.
        XSDSchema otherSchema = xsdResource.getSchema();
        for (XSDSchemaContent content : otherSchema.getContents())
        {
          if (content instanceof XSDSchemaDirective)
          {
            XSDSchemaDirective schemaDirective = (XSDSchemaDirective)content;
            String type = null;
            if (content instanceof XSDImport)
            {
              type = "XSDImport";
            }
            else if (content instanceof XSDInclude)
            {
              type = "XSDInclude";
            }
            else if (content instanceof XSDRedefine)
            {
              type = "XSDRedefine";
            }
            else
            {
              type = "unknown";
            }
            if (schemaDirective.getResolvedSchema() == null)
            {
              type += "-unresolved";
            }
            // Store the item in our hash to return to caller
            hash.put(schemaDirective.getSchemaLocation(), type);

            // Recurse down the tree into the next schema
            // using the schema API's
            XSDSchema nextSchema = schemaDirective.getResolvedSchema();
            if (null != nextSchema) 
            {
              mapImpInclRedef(nextSchema, hash, 1);
            }
          }
        }
      }
    }
    // If none were found, return null
    if (hash.size() == 0)
    {
      return null;
    }
    return hash;
  }

  /**
   * Recursive worker method implementing {@link #hasImpInclRedef(XSDSchema)}
   * and {@link #hasImpInclRedef2(XSDSchema)}. 
   *
   * <p>This uses only the schema model library API's to look for 
   * XSDSchemaDirective objects in it's content. It then checks 
   * which specific subclass of directive each is to report and 
   * then recurses to any other schemas found.</p>
   * 
   * @param schema object to search for imports/includes/redefines
   * @param hash where keys are the URI's of any other schemas 
   * found, and values are one of 'import', 'include', 'redefine'; 
   * this object is mutated by this method
   * @param level of iteration we're on
   */
  protected static void mapImpInclRedef(XSDSchema schema, HashMap<String, String> hash, int level)
  {
    // Iterate through this schema itself to see what 
    // other schemas it *directly* import/include/redefines
    for (XSDSchemaContent schemaContent : schema.getContents())
    {
      if (schemaContent instanceof XSDSchemaDirective)
      {
        XSDSchemaDirective schemaDirective = (XSDSchemaDirective)schemaContent;
        String type = null;
        if (schemaContent instanceof XSDImport)
        {
          type = "XSDImport-level" + level;
        }
        else if (schemaContent instanceof XSDInclude)
        {
          type = "XSDInclude-level" + level;
        }
        else if (schemaContent instanceof XSDRedefine)
        {
          type = "XSDRedefine-level" + level;
        }
        else
        {
          type = "unknown-level" + level;
        }
        if (schemaDirective.getResolvedSchema() == null)
        {
          type += "-unresolved";
        }
        // Store the item in our caller's hashtable
        hash.put(schemaDirective.getSchemaLocation(), type);

        // Recurse down the tree into the next schema
        XSDSchema nextSchema = schemaDirective.getResolvedSchema();
        if (null != nextSchema) 
        {
          mapImpInclRedef(nextSchema, hash, level + 1);
        }
      }
    }
  }
}
