/*
 * Copyright 2009 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.dev.javac.asm;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.JWildcardType.BoundType;
import com.google.gwt.core.ext.typeinfo.NotFoundException;
import com.google.gwt.dev.javac.Resolver;
import com.google.gwt.dev.javac.TypeParameterLookup;
import com.google.gwt.dev.javac.typemodel.JClassType;
import com.google.gwt.dev.javac.typemodel.JGenericType;
import com.google.gwt.dev.javac.typemodel.JParameterizedType;
import com.google.gwt.dev.javac.typemodel.JRealClassType;
import com.google.gwt.dev.javac.typemodel.JTypeParameter;
import com.google.gwt.dev.javac.typemodel.JWildcardType;
import com.google.gwt.dev.util.Name;

import org.objectweb.asm.signature.SignatureVisitor;

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

/**
 * Resolve a single parameterized type.
 */
public class ResolveTypeSignature extends EmptySignatureVisitor {

  private final Resolver resolver;
  private final TreeLogger logger;
  private final JType[] returnTypeRef;
  private final TypeParameterLookup lookup;
  private final char wildcardMatch;
  private final JClassType enclosingClass;

  private JClassType outerClass;
  private final List<JType[]> args = new ArrayList<JType[]>();
  private int arrayDepth = 0;

  /**
   * Resolve a parameterized type.
   *
   * @param resolver
   * @param logger
   * @param returnTypeRef "pointer" to return location, ie. 1-element array
   * @param lookup
   * @param enclosingClass
   */
  public ResolveTypeSignature(Resolver resolver, TreeLogger logger,
      JType[] returnTypeRef, TypeParameterLookup lookup, JClassType enclosingClass) {
    this(resolver, logger, returnTypeRef, lookup, enclosingClass, '=');
  }

  public ResolveTypeSignature(Resolver resovler, TreeLogger logger,
      JType[] returnTypeRef, TypeParameterLookup lookup, JClassType enclosingClass,
      char wildcardMatch) {
    this.resolver = resovler;
    this.logger = logger;
    this.returnTypeRef = returnTypeRef;
    this.lookup = lookup;
    this.enclosingClass = enclosingClass;
    this.wildcardMatch = wildcardMatch;
  }

  @Override
  public SignatureVisitor visitArrayType() {
    ++arrayDepth;
    return this;
  }

  @Override
  public void visitBaseType(char descriptor) {
    switch (descriptor) {
      case 'V':
        returnTypeRef[0] = JPrimitiveType.VOID;
        break;
      case 'B':
        returnTypeRef[0] = JPrimitiveType.BYTE;
        break;
      case 'J':
        returnTypeRef[0] = JPrimitiveType.LONG;
        break;
      case 'Z':
        returnTypeRef[0] = JPrimitiveType.BOOLEAN;
        break;
      case 'I':
        returnTypeRef[0] = JPrimitiveType.INT;
        break;
      case 'S':
        returnTypeRef[0] = JPrimitiveType.SHORT;
        break;
      case 'C':
        returnTypeRef[0] = JPrimitiveType.CHAR;
        break;
      case 'F':
        returnTypeRef[0] = JPrimitiveType.FLOAT;
        break;
      case 'D':
        returnTypeRef[0] = JPrimitiveType.DOUBLE;
        break;
      default:
        throw new IllegalStateException("Unrecognized base type " + descriptor);
    }
    // this is the last visitor called on this visitor
    visitEnd();
  }

  @Override
  public void visitClassType(String internalName) {
    assert Name.isInternalName(internalName);
    outerClass = enclosingClass;
    JRealClassType classType = resolver.findByInternalName(internalName);
    if (classType == null) {
      logger.log(TreeLogger.ERROR, "Unable to find class " + internalName);
      // Replace bound with Object if we can't find the class.
      returnTypeRef[0] = resolver.getTypeOracle().getJavaLangObject();
      return;
    }
    if (!resolver.resolveClass(logger, classType)) {
      // already logged why it failed.
      // Ignores the return value to be consistent with the behavior of
      // CompilationUnitTypeOracleUpdater.
    }
    returnTypeRef[0] = classType;
  }

  @Override
  public void visitEnd() {
    if (returnTypeRef[0] == null) {
      return;
    }
    resolveGenerics();
  }

  @Override
  public void visitInnerClassType(String innerName) {
    // Called after visitClass has already been called, and we will
    // successively refine the class by going into its inner classes.
    assert returnTypeRef[0] != null;
    resolveGenerics();
    outerClass = (JClassType) returnTypeRef[0];
    JClassType searchClass = outerClass;
    try {
      JParameterizedType pt = searchClass.isParameterized();
      if (pt != null) {
        searchClass = pt.getBaseType();
      }
      returnTypeRef[0] = searchClass.getNestedType(innerName);
    } catch (NotFoundException e) {
      logger.log(TreeLogger.ERROR, "Unable to resolve inner class " + innerName
          + " in " + searchClass, e);
    }
  }

  @Override
  public void visitTypeArgument() {
    JType[] arg = new JType[1]; // This could be int[] for example
    arg[0] = resolver.getTypeOracle().getWildcardType(
        JWildcardType.BoundType.UNBOUND,
        resolver.getTypeOracle().getJavaLangObject());
    args.add(arg);
  }

  @Override
  public SignatureVisitor visitTypeArgument(char wildcard) {
    JType[] arg = new JType[1];
    args.add(arg);
    // TODO(jat): should we pass enclosingClass here instead of null?
    // not sure what the enclosing class of a type argument means, but
    // I haven't found a case where it is actually used while processing
    // the type argument.
    return new ResolveTypeSignature(resolver, logger, arg, lookup, null, wildcard);
  }

  @Override
  public void visitTypeVariable(String name) {
    returnTypeRef[0] = lookup.lookup(name);
    // this is the last visitor called on this visitor
    visitEnd();
  }

  /**
   * Merge the bounds from the declared type parameters into the type arguments
   * for this type if necessary.
   *
   * <pre>
   * Example:
   * class Foo<T extends Bar> ...
   *
   * Foo<?> foo
   *
   * foo needs to have bounds ? extends Bar.
   * </pre>
   *
   * <p>
   * Currently we only deal with unbound wildcards as above, which matches
   * existing TypeOracleUpdater behavior. However, this may need to be
   * extended.
   *
   * @param typeParams
   * @param typeArgs
   */
  private void mergeTypeParamBounds(JTypeParameter[] typeParams,
      JClassType[] typeArgs) {
    int n = typeArgs.length;
    for (int i = 0; i < n; ++i) {
      JWildcardType wildcard = typeArgs[i].isWildcard();
      // right now we only replace Foo<?> with the constraints defined on the
      // definition (which appears to match the existing TypeOracleUpdater)
      // but other cases may need to be handled.
      if (wildcard != null
          && wildcard.getBoundType() == BoundType.UNBOUND
          && wildcard.getBaseType() == resolver.getTypeOracle().getJavaLangObject()
          && typeParams[i].getBaseType() != null) {
        typeArgs[i] = resolver.getTypeOracle().getWildcardType(
            BoundType.UNBOUND, typeParams[i].getBaseType());
      }
    }
  }

  private JType resolveGeneric(JType type, JClassType outer,
      JClassType[] typeArgs) {
    JGenericType genericType = (JGenericType) type.isGenericType();
    if (genericType != null) {
      int actual = typeArgs.length;
      JTypeParameter[] typeParams = genericType.getTypeParameters();
      int expected = typeParams.length;
      if (actual == 0 && expected > 0) {
        // If no type parameters were supplied, this is a raw type usage.
        type = genericType.getRawType();
      } else {
        if (actual != expected) {
          throw new IllegalStateException("Incorrect # of type parameters to "
              + genericType.getQualifiedBinaryName() + ": expected " + expected
              + ", actual=" + actual);
        }
        JClassType genericEnc = genericType.getEnclosingType();
        if (outer == null && genericEnc != null) {
          // Sometimes the signature is like Foo$Bar<H> even if Foo is a
          // generic class. The cases I have seen are where Foo's type
          // parameter is also named H and has the same bounds. That
          // manifests itself as getting visitClassType("Foo$Bar") and
          // then VisitTypeArgument/etc, rather than the usual
          // visitClassType("Foo"), visitTypeArgument/etc,
          // visitInnerClass("Bar"), visitTypeArgument/etc.
          //
          // So, in this case we have to build our own chain of enclosing
          // classes here, properly parameterizing any generics along the
          // way.
          // TODO(jat): more testing to validate this assumption
          JClassType[] outerArgs = null;
          JGenericType genericEncGeneric = genericEnc.isGenericType();
          if (genericEncGeneric != null) {
            JTypeParameter[] encTypeParams = genericEncGeneric.getTypeParameters();
            int n = encTypeParams.length;
            outerArgs = new JClassType[n];
            for (int i = 0; i < n; ++i) {
              outerArgs[i] = lookup.lookup(encTypeParams[i].getName());
              if (outerArgs[i] == null) {
                // check to see if our current type has a parameter of the same
                // name, and use it if so.
                for (int j = 0; j < expected; ++j) {
                  if (typeParams[j].getName().equals(encTypeParams[j].getName())) {
                    outerArgs[i] = typeArgs[j];
                    break;
                  }
                }
              }
              assert outerArgs[i] != null : "Unable to resolve type parameter "
                  + encTypeParams[i].getName() + " in enclosing type "
                  + genericEnc + " of type " + genericType;
            }
          }
          outer = (JClassType) resolveGeneric(genericEnc, null, outerArgs);
        }
        try {
          mergeTypeParamBounds(typeParams, typeArgs);
          type = resolver.getTypeOracle().getParameterizedType(genericType,
              outer, typeArgs);
        } catch (IllegalArgumentException e) {
          // Can't use toString on typeArgs as they aren't completely built
          // yet, so we have to roll our own.
          StringBuilder buf = new StringBuilder();
          buf.append("Unable to build parameterized type ");
          buf.append(genericType);
          String prefix = " with args <";
          for (JClassType typeArg : typeArgs) {
            buf.append(prefix).append(typeArg.getName());
            prefix = ", ";
          }
          if (", ".equals(prefix)) {
            buf.append('>');
          }
          logger.log(TreeLogger.ERROR, buf.toString(), e);
          type = genericType.getRawType();
        }
      }
    }
    return type;
  }

  private void resolveGenerics() {
    JGenericType genericType = (JGenericType) returnTypeRef[0].isGenericType();
    if (genericType != null) {
      int actual = args.size();
      JClassType[] typeArgs = new JClassType[actual];
      for (int i = 0; i < actual; ++i) {
        JType type = args.get(i)[0];
        if (!(type instanceof JClassType)) {
          logger.log(TreeLogger.ERROR, "Parameterized type argument is " + type
              + ", expected reference type");
        } else {
          typeArgs[i] = (JClassType) type;
        }
      }
      returnTypeRef[0] = resolveGeneric(genericType, outerClass, typeArgs);
      args.clear();
    }
    for (int i = 0; i < arrayDepth; ++i) {
      returnTypeRef[0] = resolver.getTypeOracle().getArrayType(returnTypeRef[0]);
    }
    switch (wildcardMatch) {
      case '=':
        // nothing to do for an exact match
        break;
      case '*':
        returnTypeRef[0] = resolver.getTypeOracle().getWildcardType(
            JWildcardType.BoundType.UNBOUND, (JClassType) returnTypeRef[0]);
        break;
      case '+':
        // ? extends T
        returnTypeRef[0] = resolver.getTypeOracle().getWildcardType(
            JWildcardType.BoundType.EXTENDS, (JClassType) returnTypeRef[0]);
        break;
      case '-':
        // ? super T
        returnTypeRef[0] = resolver.getTypeOracle().getWildcardType(
            JWildcardType.BoundType.SUPER, (JClassType) returnTypeRef[0]);
        break;
    }
    if (returnTypeRef[0] instanceof JClassType) {
      // Only JClassTypes can be an outer class
      outerClass = (JClassType) returnTypeRef[0];
    }
  }
}
