/*
 * Copyright 2008 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.core.ext.typeinfo;

import com.google.gwt.core.ext.typeinfo.JWildcardType.BoundType;
import com.google.gwt.dev.util.collect.IdentityHashMap;
import com.google.gwt.dev.util.collect.Lists;
import com.google.gwt.dev.util.collect.Maps;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Represents a parameterized type in a declaration.
 */
public class JParameterizedType extends JMaybeParameterizedType {
  /**
   * Create a parameterized type along with any necessary enclosing
   * parameterized types. Enclosing parameterized types are necessary when the
   * base type is a non-static member and the enclosing type is also generic.
   */
  private static JParameterizedType createParameterizedTypeRecursive(
      JGenericType baseType, Map<JTypeParameter, JClassType> substitutionMap) {
    JClassType enclosingType = baseType.getEnclosingType();
    if (baseType.isMemberType() && !baseType.isStatic()) {
      // This base type is a non-static generic type so we build the necessary
      // enclosing parameterized type and update the enclosing type to be
      // a parameterized type.
      JGenericType isGenericEnclosingType = enclosingType.isGenericType();
      if (isGenericEnclosingType != null) {
        enclosingType = createParameterizedTypeRecursive(
            isGenericEnclosingType, substitutionMap);
      }
    }

    JTypeParameter[] typeParameters = baseType.getTypeParameters();
    JClassType[] newTypeArgs = new JClassType[typeParameters.length];
    TypeOracle oracle = baseType.getOracle();
    for (int i = 0; i < newTypeArgs.length; ++i) {
      JClassType newTypeArg = substitutionMap.get(typeParameters[i]);
      if (newTypeArg == null) {
        newTypeArg = oracle.getWildcardType(BoundType.EXTENDS,
            typeParameters[i].getFirstBound());
      }

      newTypeArgs[i] = newTypeArg;
    }

    JParameterizedType parameterizedType = oracle.getParameterizedType(
        baseType, enclosingType, newTypeArgs);
    return parameterizedType;
  }

  private final JClassType enclosingType;

  private List<JClassType> interfaces;

  /**
   * This map records the JClassType that should be used in place of a given
   * {@link JTypeParameter}.
   */
  private Map<JTypeParameter, JClassType> lazySubstitutionMap;

  private JClassType lazySuperclass;

  private final AbstractMembers members;

  private final List<JClassType> typeArgs;

  JParameterizedType(JGenericType baseType, JClassType enclosingType,
      JClassType[] typeArgs) {
    super.setBaseType(baseType);

    this.enclosingType = enclosingType;

    // NOTE: this instance is not considered a nested type of the enclosing type

    final JParameterizedType parameterizedType = this;
    members = new DelegateMembers(this, baseType, new Substitution() {
      public JType getSubstitution(JType type) {
        return type.getSubstitutedType(parameterizedType);
      }
    });

    this.typeArgs = Lists.create(typeArgs);
    assert (this.typeArgs.indexOf(null) == -1)
        : "Unresolved typeArg creating JParameterizedType from " + baseType;

    // NOTE: Can't perform substitutions until we are done building
  }

  @Override
  public JConstructor findConstructor(JType[] paramTypes) {
    return members.findConstructor(paramTypes);
  }

  @Override
  public JField findField(String name) {
    return members.findField(name);
  }

  @Override
  public JMethod findMethod(String name, JType[] paramTypes) {
    return members.findMethod(name, paramTypes);
  }

  @Override
  public JClassType findNestedType(String typeName) {
    return members.findNestedType(typeName);
  }

  @Override
  public JConstructor getConstructor(JType[] paramTypes)
      throws NotFoundException {
    return members.getConstructor(paramTypes);
  }

  @Override
  public JConstructor[] getConstructors() {
    return members.getConstructors();
  }

  @Override
  public JClassType getEnclosingType() {
    return enclosingType;
  }

  @Override
  public JField getField(String name) {
    return members.getField(name);
  }

  @Override
  public JField[] getFields() {
    return members.getFields();
  }

  @Override
  public JClassType[] getImplementedInterfaces() {
    if (interfaces == null) {
      interfaces = new ArrayList<JClassType>();
      JClassType[] intfs = getBaseType().getImplementedInterfaces();
      for (JClassType intf : intfs) {
        JClassType newIntf = intf.getSubstitutedType(this);
        interfaces.add(newIntf);
      }
      interfaces = Lists.normalize(interfaces);
    }
    return interfaces.toArray(TypeOracle.NO_JCLASSES);
  }

  @Override
  public JMethod[] getInheritableMethods() {
    return members.getInheritableMethods();
  }

  @Override
  public JMethod getMethod(String name, JType[] paramTypes)
      throws NotFoundException {
    return members.getMethod(name, paramTypes);
  }

  @Override
  public JMethod[] getMethods() {
    return members.getMethods();
  }

  @Override
  public JClassType getNestedType(String typeName) throws NotFoundException {
    return members.getNestedType(typeName);
  }

  @Override
  public JClassType[] getNestedTypes() {
    return members.getNestedTypes();
  }

  /**
   * @deprecated See {@link #getQualifiedSourceName()}
   */
  @Deprecated
  public String getNonParameterizedQualifiedSourceName() {
    return getQualifiedSourceName();
  }

  @Override
  public JMethod[] getOverloads(String name) {
    return members.getOverloads(name);
  }

  @Override
  public JMethod[] getOverridableMethods() {
    return members.getOverridableMethods();
  }

  @Override
  public String getParameterizedQualifiedSourceName() {
    StringBuffer sb = new StringBuffer();

    if (getEnclosingType() != null) {
      sb.append(getEnclosingType().getParameterizedQualifiedSourceName());
      sb.append(".");
      sb.append(getSimpleSourceName());
    } else {
      sb.append(getQualifiedSourceName());
    }

    if (typeArgs.size() > 0) {
      sb.append('<');
      boolean needComma = false;
      for (JType typeArg : typeArgs) {
        if (needComma) {
          sb.append(", ");
        } else {
          needComma = true;
        }
        sb.append(typeArg.getParameterizedQualifiedSourceName());
      }
      sb.append('>');
    } else {
      /*
       * Non-static, inner classes of generic types are modeled as generic, even
       * if they do not declare type parameters or reference the type parameters
       * of their enclosing generic type.
       */
    }

    return sb.toString();
  }

  @Override
  public String getQualifiedBinaryName() {
    return getBaseType().getQualifiedBinaryName();
  }

  /**
   * Everything is fully qualified and includes the &lt; and &gt; in the
   * signature.
   */
  @Override
  public String getQualifiedSourceName() {
    return getBaseType().getQualifiedSourceName();
  }

  public JClassType getRawType() {
    return getBaseType().getRawType();
  }

  /**
   * In this case, the raw type name.
   */
  @Override
  public String getSimpleSourceName() {
    return getBaseType().getSimpleSourceName();
  }

  /*
   * Goal: Return a list of possible subtypes of this parameterized type. In the
   * event that we have generic subtypes and we cannot resolve the all of the
   * type arguments, we need to wildcard types in place of the arguments that we
   * cannot resolve.
   * 
   * Algorithm: - Ask generic type for its subtypes - Filter subtypes of the
   * generic which cannot be our subtype.
   */
  @Override
  public JClassType[] getSubtypes() {
    List<JClassType> subtypeList = new ArrayList<JClassType>();

    // Parameterized types are not tracked in the subtype hierarchy; ask base
    // type
    JClassType[] genericSubtypes = getBaseType().getSubtypes();
    for (JClassType subtype : genericSubtypes) {
      // Could be a subtype depending on how it is substituted
      Map<JTypeParameter, JClassType> substitutions = findSubtypeSubstitution(subtype);
      if (substitutions != null) {
        JGenericType genericType = subtype.isGenericType();
        if (genericType != null) {
          subtype = createParameterizedTypeRecursive(genericType, substitutions);
        } else {
          // If this is not a generic type then there should not be any
          // substitution.
          assert (substitutions.isEmpty());
        }

        subtypeList.add(subtype);
      }
    }

    return subtypeList.toArray(TypeOracle.NO_JCLASSES);
  }

  @Override
  public JClassType getSuperclass() {
    if (isInterface() != null) {
      return null;
    }

    if (lazySuperclass == null) {
      JGenericType baseType = getBaseType();
      JClassType superclass = baseType.getSuperclass();
      assert (superclass != null);
      lazySuperclass = superclass.getSubstitutedType(this);
    }

    return lazySuperclass;
  }

  public JClassType[] getTypeArgs() {
    return typeArgs.toArray(TypeOracle.NO_JCLASSES);
  }

  @Override
  public JGenericType isGenericType() {
    return null;
  }

  @Override
  public JParameterizedType isParameterized() {
    return this;
  }

  @Override
  public JRawType isRawType() {
    return null;
  }

  @Override
  public JWildcardType isWildcard() {
    return null;
  }

  @Override
  public String toString() {
    if (isInterface() != null) {
      return "interface " + getParameterizedQualifiedSourceName();
    }

    return "class " + getParameterizedQualifiedSourceName();
  }

  @Override
  protected JClassType findNestedTypeImpl(String[] typeName, int index) {
    return members.findNestedTypeImpl(typeName, index);
  }

  @Override
  protected void getInheritableMethodsOnSuperclassesAndThisClass(
      Map<String, JMethod> methodsBySignature) {
    members.getInheritableMethodsOnSuperclassesAndThisClass(methodsBySignature);
  }

  /**
   * Gets the methods declared in interfaces that this type extends. If this
   * type is a class, its own methods are not added. If this type is an
   * interface, its own methods are added. Used internally by
   * {@link #getOverridableMethods()}.
   * 
   * @param methodsBySignature
   */
  @Override
  protected void getInheritableMethodsOnSuperinterfacesAndMaybeThisInterface(
      Map<String, JMethod> methodsBySignature) {
    members.getInheritableMethodsOnSuperinterfacesAndMaybeThisInterface(methodsBySignature);
  }

  @Override
  JClassType getSubstitutedType(JParameterizedType parameterizedType) {
    maybeInitializeTypeParameterSubstitutionMap();

    if (this == parameterizedType) {
      return this;
    }

    JClassType[] newTypeArgs = new JClassType[typeArgs.size()];
    for (int i = 0; i < newTypeArgs.length; ++i) {
      newTypeArgs[i] = typeArgs.get(i).getSubstitutedType(parameterizedType);
    }

    return getOracle().getParameterizedType(getBaseType(), getEnclosingType(),
        newTypeArgs);
  }

  /**
   * Returns the {@link JClassType} that is a substitute for the given
   * {@link JTypeParameter}. If there is no substitution, the original
   * {@link JTypeParameter} is returned.
   */
  JClassType getTypeParameterSubstitution(JTypeParameter typeParameter) {
    maybeInitializeTypeParameterSubstitutionMap();

    JClassType substitute = lazySubstitutionMap.get(typeParameter);
    if (substitute != null) {
      return substitute;
    }

    return typeParameter;
  }

  boolean hasTypeArgs(JClassType[] otherArgTypes) {
    if (otherArgTypes.length != typeArgs.size()) {
      return false;
    }

    for (int i = 0; i < otherArgTypes.length; ++i) {
      // Identity tests are ok since identity is durable within an oracle.
      //
      if (otherArgTypes[i] != typeArgs.get(i)) {
        return false;
      }
    }

    return true;
  }

  /**
   * Initialize a map of substitutions for {@link JTypeParameter}s to
   * corresponding {@link JClassType}s. This can only be initialized after the
   * {@link com.google.gwt.dev.javac.TypeOracleMediator TypeOracleMediator} has
   * fully resolved all of the {@link JClassType}s.
   */
  void maybeInitializeTypeParameterSubstitutionMap() {
    if (lazySubstitutionMap != null) {
      return;
    }
    lazySubstitutionMap = new IdentityHashMap<JTypeParameter, JClassType>();

    JParameterizedType currentParameterizedType = this;

    while (currentParameterizedType != null) {
      JGenericType genericType = currentParameterizedType.getBaseType();
      JTypeParameter[] typeParameters = genericType.getTypeParameters();
      JClassType[] typeArguments = currentParameterizedType.getTypeArgs();

      for (JTypeParameter typeParameter : typeParameters) {
        lazySubstitutionMap.put(typeParameter,
            typeArguments[typeParameter.getOrdinal()]);
      }

      if (currentParameterizedType.isStatic()) {
        break;
      }

      JClassType maybeParameterizedType = currentParameterizedType.getEnclosingType();
      if (maybeParameterizedType == null
          || maybeParameterizedType.isParameterized() == null) {
        break;
      }
      currentParameterizedType = maybeParameterizedType.isParameterized();
    }
    lazySubstitutionMap = Maps.normalize(lazySubstitutionMap);
  }

  void setTypeArguments(JClassType[] typeArgs) {
    this.typeArgs.addAll(Arrays.asList(typeArgs));
  }

  /**
   * Returns a map of substitutions that will make the subtype a proper subtype
   * of this parameterized type. The map maybe empty in the case that it is
   * already an exact subtype.
   */
  private Map<JTypeParameter, JClassType> findSubtypeSubstitution(
      JClassType subtype) {
    Map<JTypeParameter, JClassType> substitutions = new IdentityHashMap<JTypeParameter, JClassType>();

    // Get the supertype hierarchy. If this JParameterizedType exists
    // exactly in this set we are done.
    Set<JClassType> supertypeHierarchy = getFlattenedSuperTypeHierarchy(subtype);
    if (supertypeHierarchy.contains(this)) {
      return substitutions;
    }

    /*
     * Try to find a parameterized supertype whose base type is the same as our
     * own. Because that parameterized supertype might be made into ourself via
     * substitution.
     */
    for (JClassType candidate : supertypeHierarchy) {
      JParameterizedType parameterizedCandidate = candidate.isParameterized();
      if (parameterizedCandidate == null) {
        // If not parameterized then there is no substitution possible.
        continue;
      }

      if (parameterizedCandidate.getBaseType() != getBaseType()) {
        // This candidate be parameterized to us.
        continue;
      }

      /*
       * We have a parameterization of our base type. Now we need to see if it
       * is possible to parameterize subtype such that candidate becomes
       * equivalent to us.
       */
      JClassType[] candidateTypeArgs = parameterizedCandidate.getTypeArgs();
      JClassType[] myTypeArgs = getTypeArgs();
      for (int i = 0; i < myTypeArgs.length; ++i) {
        JClassType otherTypeArg = candidateTypeArgs[i];
        JClassType myTypeArg = myTypeArgs[i];

        if (myTypeArg == otherTypeArg) {
          // There are identical so there is no substitution that is needed.
          continue;
        }

        JTypeParameter otherTypeParameter = otherTypeArg.isTypeParameter();
        if (otherTypeParameter == null) {
          // Not a type parameter and not equal so no substitution can make it
          // equal.
          return null;
        }

        if (!otherTypeParameter.isAssignableFrom(myTypeArg)) {
          // Make sure that my type argument can be substituted for this type
          // parameter.
          return null;
        }

        substitutions.put(otherTypeParameter, myTypeArg);
      }
    }

    // Legal substitution can be made and is record in substitutions.
    return substitutions;
  }
}
