/*
 * 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.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JWildcardType.BoundType;
import com.google.gwt.core.ext.typeinfo.test.CA;
import com.google.gwt.core.ext.typeinfo.test.CB;
import com.google.gwt.core.ext.typeinfo.test.CC;
import com.google.gwt.dev.util.log.PrintWriterTreeLogger;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * Test for {@link JWildcardType}.
 */
public class JWildcardTypeTest extends JDelegatingClassTypeTestBase {
  private final boolean logToConsole = false;
  private final ModuleContext moduleContext = new ModuleContext(logToConsole
      ? new PrintWriterTreeLogger() : TreeLogger.NULL,
      "com.google.gwt.core.ext.typeinfo.TypeOracleTest");

  public JWildcardTypeTest() throws UnableToCompleteException {
  }

  @Override
  public void testFindConstructor() {
    // Wildcard types do not have constructors
  }

  @Override
  public void testFindNestedType() {
    // Wildcard do not have nested types...
  }

  @Override
  public void testGetConstructors() {
  }

  @Override
  public void testGetEnclosingType() {
    // Wildcard do not have nested types...
  }

  @Override
  public void testGetErasedType() throws NotFoundException {
    TypeOracle oracle = moduleContext.getOracle();
    JClassType numberType = oracle.getType(Number.class.getCanonicalName());

    // Tests that ? extends Number erases to number.
    JWildcardType upperBoundWildcard = oracle.getWildcardType(
        BoundType.EXTENDS, numberType);
    assertEquals(numberType, upperBoundWildcard.getErasedType());

    // Tests that ? super Number erases to Object
    JWildcardType lowerBoundWildcard = oracle.getWildcardType(BoundType.SUPER,
        numberType);
    assertEquals(oracle.getJavaLangObject(), lowerBoundWildcard.getErasedType());
  }

  @Override
  public void testGetInheritableMethods() {
    // No inheritable methods
  }

  @Override
  public void testGetMethods() throws NotFoundException {
    super.testGetMethods();
  }

  @Override
  public void testGetNestedType() {
    // No nested types
  }

  @Override
  public void testGetNestedTypes() {
    // No nested types
  }

  @Override
  public void testGetOverridableMethods() {
    // No overridable methods
  }

  /**
   * Tests that {@link JWildcardType#getParameterizedQualifiedSourceName()}
   * returns the expected value. We test this because JSNI code depends on it.
   * 
   * @throws NotFoundException
   */
  public void testGetParameterizedQualifiedSourceName()
      throws NotFoundException {
    TypeOracle oracle = moduleContext.getOracle();
    JClassType numberType = oracle.getType(Number.class.getName());

    JWildcardType numberUpperBound = oracle.getWildcardType(BoundType.EXTENDS,
        numberType);
    assertEquals("? extends " + Number.class.getCanonicalName(),
        numberUpperBound.getParameterizedQualifiedSourceName());

    JWildcardType numberLowerBound = oracle.getWildcardType(BoundType.SUPER,
        numberType);
    assertEquals("? super " + Number.class.getCanonicalName(),
        numberLowerBound.getParameterizedQualifiedSourceName());

    JWildcardType unboundWildcard = oracle.getWildcardType(BoundType.UNBOUND,
        oracle.getJavaLangObject());
    assertEquals("?", unboundWildcard.getParameterizedQualifiedSourceName());
  }

  @Override
  public void testGetSubtypes() {
    // Tested by testGetSubtypes_LowerBound() and testGetSubtypes_UpperBound()
  }

  public void testGetSubtypes_LowerBound() throws NotFoundException {
    TypeOracle oracle = moduleContext.getOracle();
    // <? super Number>
    JWildcardType lowerBoundWildcard = oracle.getWildcardType(BoundType.SUPER,
        oracle.getType(Number.class.getName()));
    JClassType[] subtypes = lowerBoundWildcard.getSubtypes();
    assertEquals(0, subtypes.length);
    // assertEquals(oracle.getJavaLangObject(), subtypes[0]);
  }

  public void testGetSubtypes_UpperBound() throws NotFoundException {
    TypeOracle oracle = moduleContext.getOracle();
    // <? extends CA>
    JWildcardType upperBoundWildcard = oracle.getWildcardType(
        BoundType.EXTENDS, oracle.getType(CA.class.getName()));

    JClassType[] expected = new JClassType[] {
        oracle.getType(CB.class.getName()), oracle.getType(CC.class.getName())};
    Set<JClassType> expectedSet = new HashSet<JClassType>();
    expectedSet.addAll(Arrays.asList(expected));

    JClassType[] actual = upperBoundWildcard.getSubtypes();
    assertEquals(expectedSet.size(), actual.length);

    for (int i = 0; i < actual.length; ++i) {
      expectedSet.remove(actual[i]);
    }
    assertTrue(expectedSet.isEmpty());
  }

  @Override
  public void testIsAssignableFrom() throws NotFoundException {
    // Covered by the different testIsAssignableFrom*() variants below.
    TypeOracle oracle = moduleContext.getOracle();

    JClassType integerType = oracle.getType(Integer.class.getName());
    JClassType numberType = oracle.getType(Number.class.getName());

    // ? extends Number
    JClassType extendsNumber = oracle.getWildcardType(BoundType.EXTENDS,
        numberType);

    // ? extends Integer
    JClassType extendsInteger = oracle.getWildcardType(BoundType.EXTENDS,
        integerType);

    // Integer is not assignable from ? extends Number
    assertFalse(integerType.isAssignableFrom(extendsNumber));

    // Integer is assignable from ? extends Integer
    assertTrue(integerType.isAssignableFrom(extendsInteger));

    // Number is assignable from ? extends Integer
    assertTrue(numberType.isAssignableFrom(extendsInteger));

    // ? super Integer
    JClassType superInteger = oracle.getWildcardType(BoundType.SUPER,
        integerType);

    // Integer is assignable from ? super Integer
    assertFalse(integerType.isAssignableFrom(superInteger));

    // ? super Integer is assignable from Number
    assertTrue(superInteger.isAssignableFrom(numberType));

    JClassType superNumber = oracle.getWildcardType(BoundType.SUPER, numberType);

    // ? super Number is assignable from Integer
    assertTrue(superNumber.isAssignableFrom(integerType));

    // ? super Number is assignable from Character
    JClassType characterType = oracle.getType(Character.class.getName());
    assertTrue(superNumber.isAssignableFrom(characterType));
  }

  /**
   * Tests that <? extends Number> is assignable from <? extends Integer> and
   * that the reverse is not <code>true</code>.
   */
  public void testIsAssignableFrom_Extends_Number_To_Extends_Integer()
      throws NotFoundException {
    TypeOracle oracle = moduleContext.getOracle();
    JClassType numberType = oracle.getType(Number.class.getName());
    JClassType integerType = oracle.getType(Integer.class.getName());

    JWildcardType numberWildcard = oracle.getWildcardType(BoundType.EXTENDS,
        numberType);
    JWildcardType integerWildcard = oracle.getWildcardType(BoundType.EXTENDS,
        integerType);

    assertTrue(numberWildcard.isAssignableFrom(integerWildcard));
    assertFalse(integerWildcard.isAssignableFrom(numberWildcard));
  }

  /**
   * Tests that <? extends Object> is assignable to and from <? super Object>.
   */
  public void testIsAssignableFrom_Extends_Object_From_Super_Object() {
    TypeOracle oracle = moduleContext.getOracle();

    JClassType javaLangObject = oracle.getJavaLangObject();

    // ? super Object
    JWildcardType lowerWildcard = oracle.getWildcardType(BoundType.SUPER,
        javaLangObject);

    // ? extends Object
    JWildcardType upperWildcard = oracle.getWildcardType(BoundType.EXTENDS,
        javaLangObject);

    // ? extends Object assignable from ? super Object
    assertTrue(upperWildcard.isAssignableFrom(lowerWildcard));

    // ? super Object assignable from ? extends Object
    assertTrue(lowerWildcard.isAssignableFrom(upperWildcard));
  }

  /**
   * Tests that <? super Integer> is assignable to and from <? super Number>.
   */
  public void testIsAssignableFrom_Super_Integer_From_Super_Number()
      throws NotFoundException {
    TypeOracle oracle = moduleContext.getOracle();
    JClassType numberType = oracle.getType(Number.class.getName());
    JClassType integerType = oracle.getType(Integer.class.getName());

    JWildcardType numberWildcard = oracle.getWildcardType(BoundType.SUPER,
        numberType);
    JWildcardType integerWildcard = oracle.getWildcardType(BoundType.SUPER,
        integerType);

    assertTrue(numberWildcard.isAssignableFrom(integerWildcard));
    assertTrue(numberWildcard.isAssignableTo(integerWildcard));
    assertTrue(integerWildcard.isAssignableFrom(numberWildcard));
    assertTrue(integerWildcard.isAssignableTo(numberWildcard));
  }

  /**
   * Tests that <? super Number> is assignable to and from <? super Integer>.
   */
  public void testIsAssignableFrom_Super_Number_To_Super_Integer()
      throws NotFoundException {
    TypeOracle oracle = moduleContext.getOracle();
    JClassType numberType = oracle.getType(Number.class.getName());
    JClassType integerType = oracle.getType(Integer.class.getName());

    JWildcardType numberWildcard = oracle.getWildcardType(BoundType.SUPER,
        numberType);
    JWildcardType integerWildcard = oracle.getWildcardType(BoundType.SUPER,
        integerType);

    assertTrue(numberWildcard.isAssignableTo(integerWildcard));
    assertTrue(integerWildcard.isAssignableTo(numberWildcard));
  }

  @Override
  public void testIsAssignableTo() {
    // NOTE These cases were tested as part of testIsAssignableFrom.
  }

  /**
   * Tests that <? extends Integer> is assignable to <? extends Number> and that
   * the reverse is not <code>true</code>.
   */
  public void testIsAssignableTo_Extends_Integer_To_Extends_Number()
      throws NotFoundException {
    TypeOracle oracle = moduleContext.getOracle();
    JClassType numberType = oracle.getType(Number.class.getName());
    JClassType integerType = oracle.getType(Integer.class.getName());

    JWildcardType numberWildcard = oracle.getWildcardType(BoundType.EXTENDS,
        numberType);
    JWildcardType integerWildcard = oracle.getWildcardType(BoundType.EXTENDS,
        integerType);

    assertTrue(integerWildcard.isAssignableTo(numberWildcard));
    assertFalse(numberWildcard.isAssignableTo(integerWildcard));
  }

  /**
   * Tests that <? super Number> is assignable to and from <? super Integer>.
   */
  public void testIsAssignableTo_Super_Number_To_Super_Integer()
      throws NotFoundException {
    TypeOracle oracle = moduleContext.getOracle();
    JClassType numberType = oracle.getType(Number.class.getName());
    JClassType integerType = oracle.getType(Integer.class.getName());

    JWildcardType numberWildcard = oracle.getWildcardType(BoundType.SUPER,
        numberType);
    JWildcardType integerWildcard = oracle.getWildcardType(BoundType.SUPER,
        integerType);

    assertTrue(integerWildcard.isAssignableTo(numberWildcard));
    assertTrue(numberWildcard.isAssignableTo(integerWildcard));
  }

  @Override
  protected Substitution getSubstitution() {
    return new Substitution() {
      public JType getSubstitution(JType type) {
        return type;
      }
    };
  }

  @Override
  protected JWildcardType getTestType() throws NotFoundException {
    TypeOracle oracle = moduleContext.getOracle();
    return oracle.getWildcardType(BoundType.EXTENDS,
        oracle.getType(Number.class.getName()));
  }
}
