/*
 * 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;
import com.google.gwt.dev.util.StringInterner;

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

/**
 * Represents one of the type parameters in a generic type.
 */
public class JTypeParameter extends JDelegatingClassType implements
    com.google.gwt.core.ext.typeinfo.JTypeParameter {
  private JClassType[] bounds;
  private JGenericType declaringClass;
  private final int ordinal;
  private final String typeName;

  public JTypeParameter(String typeName, int ordinal) {
    this.typeName = StringInterner.get().intern(typeName);
    this.ordinal = ordinal;
  }

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

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

  public JClassType[] getBounds() {
    return bounds;
  }

  public JGenericType getDeclaringClass() {
    return declaringClass;
  }

  @Override
  public JClassType getEnclosingType() {
    // Type parameters do not have an enclosing type.
    return null;
  }

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

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

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

  @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 getName() {
    return typeName;
  }

  public int getOrdinal() {
    return ordinal;
  }

  @Override
  public String getParameterizedQualifiedSourceName() {
    return typeName;
  }

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

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

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

  @Override
  public JClassType[] getSubtypes() {
    JClassType[] subtypes = super.getSubtypes();
    List<JClassType> intersectionTypes = new ArrayList<JClassType>();

    if (getFirstBound().isInterface() == null
        && isAssignableFrom(getFirstBound())) {
      // Include the first bound as a subtype if it is not an interface and it
      // is assignable to all of our bounds.
      intersectionTypes.add(getFirstBound());
    }

    for (JClassType subtype : subtypes) {
      if (isAssignableFrom(subtype)) {
        intersectionTypes.add(subtype);
      }
    }

    // Only types that intersect with all our bounds make it here.
    return intersectionTypes.toArray(TypeOracle.NO_JCLASSES);
  }

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

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

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

  @Override
  public JTypeParameter isTypeParameter() {
    return this;
  }

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

  public void setBounds(JClassType[] bounds) {
    this.bounds = bounds;
    super.setBaseType(bounds[0]);
  }

  @Override
  public String toString() {
    if (getBaseType().isInterface() != null) {
      return "interface " + getQualifiedSourceName();
    } else {
      return "class " + getQualifiedSourceName();
    }
  }

  @Override
  JClassType getSubstitutedType(JParameterizedType parameterizedType) {
    return parameterizedType.getTypeParameterSubstitution(this);
  }

  void setDeclaringClass(JGenericType declaringClass) {
    this.declaringClass = declaringClass;
  }

  private String toString(boolean simpleName) {
    StringBuffer sb = new StringBuffer();
    sb.append(typeName);
    sb.append(" extends ");
    for (int i = 0; i < bounds.length; ++i) {
      if (i != 0) {
        sb.append(" & ");
      }

      String boundName;
      if (simpleName) {
        boundName = bounds[i].getSimpleSourceName();
      } else {
        boundName = bounds[i].getParameterizedQualifiedSourceName();
      }
      sb.append(boundName);
    }

    return sb.toString();
  }
}
