/*
 * 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.JClassType;
import com.google.gwt.core.ext.typeinfo.JGenericType;
import com.google.gwt.core.ext.typeinfo.JParameterizedType;
import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
import com.google.gwt.core.ext.typeinfo.JRealClassType;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.JTypeParameter;
import com.google.gwt.core.ext.typeinfo.JWildcardType;
import com.google.gwt.core.ext.typeinfo.NotFoundException;
import com.google.gwt.core.ext.typeinfo.JWildcardType.BoundType;
import com.google.gwt.dev.asm.signature.SignatureVisitor;
import com.google.gwt.dev.javac.Resolver;
import com.google.gwt.dev.javac.TypeParameterLookup;
import com.google.gwt.dev.util.Name;

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

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

  private final Resolver resolver;
  private final Map<String, JRealClassType> binaryMapper;
  private final TreeLogger logger;
  private final JType[] returnTypeRef;
  private final TypeParameterLookup lookup;
  private final char wildcardMatch;
  private final JClassType enclosingClass;

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

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

  public ResolveTypeSignature(Resolver resovler,
      Map<String, JRealClassType> binaryMapper,
      TreeLogger logger, JType[] returnTypeRef,
      TypeParameterLookup lookup, JClassType enclosingClass,
      char wildcardMatch) {
    this.resolver = resovler;
    this.binaryMapper = binaryMapper;
    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 = binaryMapper.get(internalName);
    // TODO(jat): failures here are likely binary-only annotations or local
    // classes that have been elided from TypeOracle -- what should we do in
    // those cases?  Currently we log an error and replace them with Object,
    // but we may can do something better.
    boolean resolveSuccess = classType == null ? false
        : resolver.resolveClass(logger, classType);
    returnTypeRef[0] = classType;
    if (!resolveSuccess || returnTypeRef[0] == null) {
      logger.log(TreeLogger.ERROR, "Unable to resolve class " + internalName);
      // Replace bound with Object if we can't resolve the class.
      returnTypeRef[0] = resolver.getTypeOracle().getJavaLangObject();
    }
  }

  @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, binaryMapper, 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 TypeOracleMediator 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 TypeOracleMediator)
      // 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 = 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 = 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];
    }
  }
}
