/*
 * 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.dev.javac.typemodel;

import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.NotFoundException;

/**
 * Represents a wildcard type argument to a parameterized type.
 */
public class JWildcardType extends JDelegatingClassType implements
    com.google.gwt.core.ext.typeinfo.JWildcardType {

  private final BoundType boundType;
  private JClassType[] lazyLowerBounds;
  private JClassType[] lazyUpperBounds;

  JWildcardType(BoundType boundType, JClassType typeBound) {
    this.boundType = boundType;
    super.setBaseType(typeBound);
  }

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

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

  public BoundType getBoundType() {
    return boundType;
  }

  @Override
  public JClassType getErasedType() {
    return getUpperBound().getErasedType();
  }

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

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

  public JClassType getFirstBound() {
    return getBaseType();
  }

  /**
   * Returns the lower bounds of this wildcard type. If no lower bounds were
   * declared, an empty array is returned.
   * 
   * @return the lower bounds of this wildcard type
   */
  public JClassType[] getLowerBounds() {
    if (lazyLowerBounds == null) {
      if (isUpperBound()) {
        lazyLowerBounds = TypeOracle.NO_JCLASSES;
      } else {
        lazyLowerBounds = new JClassType[]{getFirstBound()};
      }
    }
    return lazyLowerBounds;
  }

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

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

  @Override
  public String getQualifiedBinaryName() {
    // TODO(jat): !! does a binary name have meaning for a wildcard?
    return toString(true);
  }

  @Override
  public String getQualifiedSourceName() {
    return toString(false);
  }

  @Override
  public String getSimpleSourceName() {
    return toString(true);
  }

  @Override
  public JClassType[] getSubtypes() {
    if (isUpperBound()) {
      return getFirstBound().getSubtypes();
    }

    // We are not sure what the correct behavior should be for lower bound
    // wildcards. ? super Number contains ? super T for all T extends Number,
    // but it also includes T for Number extends T. For example, Object is a
    // subtype.
    return TypeOracle.NO_JCLASSES;
  }

  @Override
  public JClassType getSuperclass() {
    if (isUpperBound()) {
      // The superclass of an upper bound is the upper bound.
      return getFirstBound();
    }

    // The only safe superclass for a ? super T is Object.
    return getOracle().getJavaLangObject();
  }

  public JClassType getUpperBound() {
    if (isUpperBound()) {
      return getFirstBound();
    }

    return getOracle().getJavaLangObject();
  }

  /**
   * Returns the upper bounds of this wildcard type. If no upper bounds were
   * declared, an array containing {@link Object} is returned.
   * 
   * @return the upper bounds of this wildcard type
   */
  public JClassType[] getUpperBounds() {
    if (lazyUpperBounds == null) {
      if (isUpperBound()) {
        lazyUpperBounds = new JClassType[]{getFirstBound()};
      } else {
        // Object is the default upper bound.
        lazyUpperBounds = new JClassType[]{getOracle().getJavaLangObject()};
      }
    }

    return lazyUpperBounds;
  }

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

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

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

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

  /**
   * Returns <code>true</code> if this instance has the same bounds that are
   * requested.
   * 
   * @param otherWildcard
   * @return <code>true</code> if this instance has the same bounds that are
   *         requested
   */
  boolean boundsMatch(JWildcardType otherWildcard) {
    return isUpperBound() == otherWildcard.isUpperBound()
        && getFirstBound() == otherWildcard.getFirstBound();
  }

  @Override
  JClassType getSubstitutedType(JParameterizedType parameterizedType) {
    return getOracle().getWildcardType(boundType,
        getFirstBound().getSubstitutedType(parameterizedType));
  }

  private boolean isUnbound() {
    return boundType == BoundType.UNBOUND;
  }

  private boolean isUpperBound() {
    return boundType != BoundType.SUPER;
  }

  private String toString(boolean simpleName) {
    String str = "?";
    if (isUnbound()) {
      return str;
    } else {
      str += (isUpperBound() ? " extends " : " super ");
      if (simpleName) {
        return str + getFirstBound().getSimpleSourceName();
      } else {
        return str + getFirstBound().getParameterizedQualifiedSourceName();
      }
    }
  }
}
