/*
 * 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.jjs;

import com.google.gwt.dev.jjs.ast.JArrayType;
import com.google.gwt.dev.jjs.ast.JClassType;
import com.google.gwt.dev.jjs.ast.JInterfaceType;
import com.google.gwt.dev.jjs.ast.JNonNullType;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JReferenceType;
import com.google.gwt.dev.jjs.ast.JTypeOracle;

import junit.framework.TestCase;

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

/**
 * Test basic operations on the types used by the JJS compiler. See
 * {@link com.google.gwt.dev.jjs.ast.JType}.
 */
public class JjsTypeTest extends TestCase {
  private JArrayType arrayOfA;
  private JArrayType arrayOfArrayOfB;
  private JReferenceType arrayOfArrayOfInt;
  private JArrayType arrayOfB;
  private JArrayType arrayOfBSub;
  private JArrayType arrayOfC;
  private JReferenceType arrayOfInt;
  private JArrayType arrayOfObject;
  private JClassType classA;
  private JClassType classB;
  private JClassType classBase;
  private JNonNullType classBaseNn;
  private JNonNullType classBnn;
  private JClassType classBSub;
  private JClassType classC;
  private JClassType classJso;
  private JClassType classJso1;
  private JClassType classJso2;
  private JClassType classObject;
  private JClassType classString;
  private JInterfaceType intfI;
  private JInterfaceType intfIBase;
  private JInterfaceType intfJ;
  private JInterfaceType intfK;
  private JProgram program;
  private SourceInfo synthSource;
  private JReferenceType typeNull;
  private JTypeOracle typeOracle;
  private JReferenceType intfSerializable;
  private JReferenceType intfCloneable;

  public void testCanTheoreticallyCast() {
    assertFalse(typeOracle.canTheoreticallyCast(classBnn, typeNull));

    assertTrue(typeOracle.canTheoreticallyCast(classBSub, classB));
    assertTrue(typeOracle.canTheoreticallyCast(classB, classBSub));

    assertTrue(typeOracle.canTheoreticallyCast(classB, classBnn));
    assertTrue(typeOracle.canTheoreticallyCast(classBnn, classB));

    assertTrue(typeOracle.canTheoreticallyCast(classB, classB));

    assertTrue(typeOracle.canTheoreticallyCast(classObject, arrayOfB));
    assertFalse(typeOracle.canTheoreticallyCast(arrayOfA, arrayOfArrayOfB));

    assertTrue(typeOracle.canTheoreticallyCast(arrayOfObject, arrayOfArrayOfB));

    assertTrue(typeOracle.canTheoreticallyCast(arrayOfB, arrayOfBSub));

    assertTrue(typeOracle.canTheoreticallyCast(classBase, intfI));
    assertFalse(typeOracle.canTheoreticallyCast(classA, intfJ));

    assertTrue(typeOracle.canTheoreticallyCast(intfIBase, intfI));

    assertTrue(typeOracle.canTheoreticallyCast(intfIBase, classBase));
    assertFalse(typeOracle.canTheoreticallyCast(intfJ, classA));

    assertTrue(typeOracle.canTheoreticallyCast(arrayOfA, intfSerializable));
    assertTrue(typeOracle.canTheoreticallyCast(intfSerializable, arrayOfA));

    assertTrue(typeOracle.canTheoreticallyCast(arrayOfA, intfCloneable));
    assertTrue(typeOracle.canTheoreticallyCast(intfCloneable, arrayOfA));
  }

  public void testCanTriviallyCast() {
    assertTrue(typeOracle.canTriviallyCast(classB, classB));

    assertTrue(typeOracle.canTriviallyCast(classBSub, classB));
    assertFalse(typeOracle.canTriviallyCast(classB, classBSub));

    assertFalse(typeOracle.canTriviallyCast(classC, classA));
    assertFalse(typeOracle.canTriviallyCast(classA, classC));

    assertTrue(typeOracle.canTriviallyCast(classB, intfI));
    assertFalse(typeOracle.canTriviallyCast(intfI, classB));

    assertTrue(typeOracle.canTriviallyCast(classB, classObject));
    assertFalse(typeOracle.canTriviallyCast(classObject, classB));

    assertTrue(typeOracle.canTriviallyCast(classB, intfI));
    assertFalse(typeOracle.canTriviallyCast(intfI, classB));

    assertTrue(typeOracle.canTriviallyCast(classBnn, classB));
    assertFalse(typeOracle.canTriviallyCast(classB, classBnn));

    assertTrue(typeOracle.canTriviallyCast(typeNull, classB));
    assertFalse(typeOracle.canTriviallyCast(classB, typeNull));

    assertTrue(typeOracle.canTriviallyCast(arrayOfBSub, arrayOfB));
    assertFalse(typeOracle.canTriviallyCast(arrayOfB, arrayOfBSub));

    assertFalse(typeOracle.canTriviallyCast(arrayOfA, arrayOfB));
    assertFalse(typeOracle.canTriviallyCast(arrayOfB, arrayOfA));

    assertFalse(typeOracle.canTriviallyCast(arrayOfArrayOfB, arrayOfB));
    assertFalse(typeOracle.canTriviallyCast(arrayOfB, arrayOfArrayOfB));

    assertTrue(typeOracle.canTriviallyCast(arrayOfArrayOfB, arrayOfObject));
    assertFalse(typeOracle.canTriviallyCast(arrayOfObject, arrayOfArrayOfB));

    assertTrue(typeOracle.canTheoreticallyCast(classJso1, classJso2));
    assertTrue(typeOracle.canTheoreticallyCast(classJso2, classJso1));

    assertTrue(typeOracle.canTheoreticallyCast(classJso1, intfK));
    assertTrue(typeOracle.canTheoreticallyCast(intfK, classJso1));

    assertTrue(typeOracle.canTheoreticallyCast(intfJ, intfK));
    assertTrue(typeOracle.canTheoreticallyCast(intfK, intfJ));

    assertTrue(typeOracle.canTriviallyCast(classJso1, classJso));

    assertTrue(typeOracle.canTriviallyCast(arrayOfA, intfSerializable));
    assertFalse(typeOracle.canTriviallyCast(intfSerializable, arrayOfA));

    assertTrue(typeOracle.canTriviallyCast(arrayOfA, intfCloneable));
    assertFalse(typeOracle.canTriviallyCast(intfCloneable, arrayOfA));

    /*
     * Test that two types cannot both be trivially castable to each other,
     * unless they are the same type.
     */
    for (JReferenceType type1 : severalTypes()) {
      for (JReferenceType type2 : severalTypes()) {
        if (type1 != type2) {
          assertFalse(typeOracle.canTriviallyCast(type1, type2)
              && typeOracle.canTriviallyCast(type2, type1));
        }
      }
    }
  }

  public void testGeneralizeTypes() {
    assertSame(classA, generalizeTypes(classA, classA));
    assertSame(classB, generalizeTypes(classB, classBnn));
    assertSame(classB, generalizeTypes(classBnn, classB));
    assertSame(classBaseNn, generalizeTypes(classBnn, classBaseNn));
    assertSame(classB, generalizeTypes(classB, typeNull));
    assertSame(classB, generalizeTypes(typeNull, classB));

    assertSame(intfIBase, generalizeTypes(intfI, intfIBase));
    assertSame(intfIBase, generalizeTypes(intfIBase, intfI));
    assertSame(classObject, generalizeTypes(intfJ, intfI));

    assertSame(classObject, generalizeTypes(arrayOfB, arrayOfInt));
    assertSame(classObject, generalizeTypes(arrayOfC, arrayOfArrayOfB));
    assertSame(arrayOfObject, generalizeTypes(arrayOfC, arrayOfB));
    assertSame(arrayOfObject, generalizeTypes(arrayOfObject, arrayOfArrayOfInt));

    assertSame(intfI, generalizeTypes(classB, intfI));
    assertSame(classObject, generalizeTypes(classB, intfJ));

    assertSame(classObject, generalizeTypes(intfI, arrayOfInt));

    assertSame(intfSerializable, generalizeTypes(intfSerializable, arrayOfA));
    assertSame(intfCloneable, generalizeTypes(intfCloneable, arrayOfA));

    for (JReferenceType type1 : severalTypes()) {
      for (JReferenceType type2 : severalTypes()) {
        JReferenceType generalized = generalizeTypes(type1, type2);
        assertTrue(typeOracle.canTriviallyCast(type1, generalized));
        assertTrue(typeOracle.canTriviallyCast(type2, generalized));
      }
    }
  }

  public void testStrongerType() {
    assertSame(classA, program.strongerType(classA, classA));
    assertSame(classBnn, program.strongerType(classB, classBnn));
    assertSame(classB, program.strongerType(classB, classBase));
    assertSame(classB, program.strongerType(classBase, classB));
    assertSame(intfI, program.strongerType(intfI, intfJ));
    assertSame(arrayOfA, program.strongerType(intfSerializable, arrayOfA));
    assertSame(arrayOfA, program.strongerType(intfCloneable, arrayOfA));
  }

  @Override
  protected void setUp() {
    createSampleProgram();
  }

  private JClassType createClass(String className, JClassType superClass,
      boolean isAbstract, boolean isFinal) {
    JClassType clazz = program.createClass(synthSource, className, isAbstract,
        isFinal);
    clazz.setSuperClass(superClass);
    return clazz;
  }

  private JInterfaceType createInterface(String className) {
    JInterfaceType intf = program.createInterface(synthSource, className);
    return intf;
  }

  private void createSampleProgram() {
    // Make the program itself
    program = new JProgram();
    typeOracle = program.typeOracle;
    synthSource = program.createSourceInfoSynthetic(JjsTypeTest.class);

    classObject = createClass("java.lang.Object", null, false, false);
    classString = createClass("java.lang.String", classObject, false, true);
    createClass("com.google.gwt.lang.Array", classObject, false, true);
    classJso = createClass("com.google.gwt.core.client.JavaScriptObject",
        classObject, false, false);

    intfSerializable = createInterface("java.io.Serializable");
    intfCloneable = createInterface("java.lang.Cloneable");

    intfIBase = createInterface("IBase");

    intfI = createInterface("I");
    intfI.addImplements(intfIBase);

    intfJ = createInterface("J");
    intfK = createInterface("K");

    classBase = createClass("Base", classObject, false, false);

    classA = createClass("A", classBase, false, false);

    classB = createClass("B", classBase, false, false);
    classB.addImplements(intfI);

    classC = createClass("C", classObject, false, false);
    classC.addImplements(intfI);

    classBSub = createClass("BSub", classB, false, false);

    classJso1 = createClass("Jso1", classJso, false, false);
    classJso1.addImplements(intfJ);
    classJso2 = createClass("Jso2", classJso, false, false);
    classJso2.addImplements(intfK);
    
    program.typeOracle.computeBeforeAST();

    // Save off some miscellaneous types to test against
    typeNull = program.getTypeNull();

    classBnn = classB.getNonNull();
    classBaseNn = classBase.getNonNull();

    arrayOfA = program.getTypeArray(classA);
    arrayOfB = program.getTypeArray(classB);
    arrayOfBSub = program.getTypeArray(classBSub);
    arrayOfC = program.getTypeArray(classC);
    arrayOfObject = program.getTypeArray(classObject);
    arrayOfInt = program.getTypeArray(program.getTypePrimitiveInt());
    arrayOfArrayOfInt = program.getTypeArray(program.getTypePrimitiveInt(), 2);

    arrayOfArrayOfB = program.getTypeArray(classB, 2);
  }

  private JReferenceType generalizeTypes(JReferenceType type1,
      JReferenceType type2) {
    List<JReferenceType> types = new ArrayList<JReferenceType>(2);
    types.add(type1);
    types.add(type2);
    return program.generalizeTypes(types);
  }

  /**
   * Return several types, for exhaustively testing basic properties.
   */
  private Collection<JReferenceType> severalTypes() {
    List<JReferenceType> types = new ArrayList<JReferenceType>();
    types.add(arrayOfA);
    types.add(arrayOfB);
    types.add(arrayOfArrayOfB);
    types.add(arrayOfBSub);
    types.add(arrayOfObject);
    types.add(classA);
    types.add(classB);
    types.add(classBSub);
    types.add(classBnn);
    types.add(classBase);
    types.add(classC);
    types.add(classObject);
    types.add(classString);
    types.add(intfI);
    types.add(intfJ);
    types.add(intfK);
    types.add(intfIBase);
    types.add(classJso1);
    types.add(classJso2);
    types.add(classJso);
    types.add(typeNull);

    return types;
  }
}
