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

import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JAbstractMethod;
import com.google.gwt.dev.javac.impl.StaticJavaResource;
import com.google.gwt.dev.resource.Resource;
import com.google.gwt.dev.util.log.AbstractTreeLogger;
import com.google.gwt.dev.util.log.PrintWriterTreeLogger;

import junit.framework.TestCase;

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

/**
 * Test {@link ApiContainer}.
 */
public class ApiContainerTest extends TestCase {

  class TestA {
    public TestA(String args) {
    }

    protected TestA(TestA a) {
    }

    public String valueOf(Object o) {
      return "a";
    }

    public String valueOf(String s) {
      return "";
    }
  }
  class TestB extends TestA {
    public TestB(TestA a) {
      super(a);
    }

    public void main(String args[]) {
      TestA x1 = new TestA("test");
      x1.valueOf("ab");
      TestB x2 = new TestB(x1);
      new TestB(x2);
    }
  }

  public static StaticJavaResource[] getScuArray() {
    return new StaticJavaResource[] {
        new StaticJavaResource("test.apicontainer.ApiClass",
            getSourceForApiClass()),
        new StaticJavaResource("test.apicontainer.NonApiClass",
            getSourceForNonApiClass()),
        new StaticJavaResource("test.nonapipackage.TestClass",
            getSourceForTestClass()),
        new StaticJavaResource("java.lang.Object", getSourceForObject()),
        new StaticJavaResource("test.apicontainer.OneMoreApiClass",
            getSourceForOneMoreApiClass()),
        new StaticJavaResource("java.newpackage.Test", getSourceForTest()),};
  }

  private static JAbstractMethod getMethodByName(String name, ApiClass apiClass) {
    return (apiClass.getApiMethodsByName(name, ApiClass.MethodType.METHOD).toArray(
        new ApiAbstractMethod[0])[0]).getMethod();
  }

  private static String getSourceForApiClass() {
    StringBuffer sb = new StringBuffer();
    sb.append("package test.apicontainer;\n");
    sb.append("public class ApiClass extends NonApiClass {\n");
    sb.append("\tpublic void apiMethod() { };\n");
    sb.append("\tpublic java.lang.Object checkParametersAndReturnTypes(ApiClass a) { return this; };\n");
    sb.append("\tpublic final java.lang.Object checkParametersAndReturnTypesFinalVersion(ApiClass a) { return this; };\n");
    sb.append("};\n");
    return sb.toString();
  }

  private static String getSourceForNonApiClass() {
    StringBuffer sb = new StringBuffer();
    sb.append("package test.apicontainer;\n");
    sb.append("class NonApiClass extends java.lang.Object {\n");
    sb.append("\tpublic void methodInNonApiClass(NonApiClass a) { };\n");
    sb.append("\tpublic int fieldInNonApiClass = 3;\n");
    sb.append("\tprotected class ApiClassInNonApiClass {\n");
    sb.append("\tprotected ApiClassInNonApiClass() { }\n");
    sb.append("\t}\n");
    sb.append("\tprotected final class AnotherApiClassInNonApiClass {\n");
    sb.append("\tprivate AnotherApiClassInNonApiClass() { }\n");
    sb.append("\t}\n");
    sb.append("}\n");
    return sb.toString();
  }

  private static String getSourceForObject() {
    StringBuffer sb = new StringBuffer();
    sb.append("package java.lang;\n");
    sb.append("public class Object {\n");
    sb.append("\tpublic void apiMethod() { }\n");
    sb.append("\tprivate void internalMethod() { }\n");
    sb.append("\tprotected native long protectedMethod();\n");
    sb.append("\tprotected void checkOverloadedAndOverridableDetection(java.lang.Object b) { }\n");
    sb.append("\tprotected final void checkOverloadedMethodAccounted(java.lang.Object b) { }\n");
    sb.append("\tpublic int apiField = 0;\n");
    sb.append("\tprotected transient int apiFieldWillBeMissing = 1;\n");
    sb.append("\tprivate int internalField = 0;\n");
    sb.append("\tprotected int protectedField=2;\n");
    sb.append("}\n");
    return sb.toString();
  }

  private static String getSourceForOneMoreApiClass() {
    StringBuffer sb = new StringBuffer();
    sb.append("package test.apicontainer;\n");
    sb.append("public class OneMoreApiClass extends java.lang.Object {\n");
    sb.append("\tprotected final void checkOverloadedMethodAccounted(test.apicontainer.OneMoreApiClass b) { }\n");
    sb.append("\tpublic void testUncheckedExceptions () { }\n");
    sb.append("};\n");
    return sb.toString();
  }

  private static String getSourceForTest() {
    StringBuffer sb = new StringBuffer();
    sb.append("package java.newpackage;\n");
    sb.append("public class Test { }\n");
    return sb.toString();
  }

  private static String getSourceForTestClass() {
    StringBuffer sb = new StringBuffer();
    sb.append("package test.nonapipackage;\n");
    sb.append("class TestClass extends java.lang.Object {\n");
    sb.append("\tpublic void method() { }\n");
    sb.append("}\n");
    return sb.toString();
  }

  ApiContainer apiCheck = null;
  AbstractTreeLogger logger = new PrintWriterTreeLogger();

  /**
   * Class hierarchy. public java.lang.Object -- test.apicontainer.NonApiClass
   * (encloses ApiClassInNonApiClass and AnotherApiClassInNonApiClass) -- public
   * test.apicontainer.ApiClass -- test.nonapipackage.TestClass
   */
  @Override
  public void setUp() throws UnableToCompleteException {
    logger.setMaxDetail(com.google.gwt.core.ext.TreeLogger.ERROR);

    apiCheck = new ApiContainer("ApiContainerTest", new HashSet<Resource>(
        Arrays.asList(getScuArray())), new HashSet<String>(), logger);
  }

  /*
   * Test if ApiContainer correctly creates an ApiContainer (for example, avoids
   * an infinite loop) when a nested class extends an outer class.
   */
  public void testApiContainerLoop() throws UnableToCompleteException {
    StringBuffer sb = new StringBuffer();
    sb.append("package java.lang;\n");
    sb.append("public class Object {\n");
    sb.append("\tpublic static class Foo extends Object{\n");
    sb.append("\t}\n");
    sb.append("}\n");
    sb.append("class Temp {\n");
    sb.append("}");

    ApiContainer apiCheckLoop = new ApiContainer("ApiClassTest",
        new HashSet<Resource>(
            Arrays.asList(new StaticJavaResource[] {new StaticJavaResource(
                "java.lang.Object", sb.toString())})), new HashSet<String>(),
        logger);
    ApiPackage javaLangPackage = apiCheckLoop.getApiPackage("java.lang");
    assertNotNull(javaLangPackage);
    assertNotNull(javaLangPackage.getApiClass("java.lang.Object"));
    assertEquals(2, javaLangPackage.getApiClassNames().size());
  }

  public void testEverything() {
    checkApiClass();
    checkApiMembers();
    checkApiPackages();
  }

  /**
   * Check if apiClasses are determined correctly. Check if inner classes are
   * classified correctly as api classes.
   */
  void checkApiClass() {
    ApiPackage package1 = apiCheck.getApiPackage("java.lang");
    ApiPackage package2 = apiCheck.getApiPackage("test.apicontainer");
    assertNotNull(package1);
    assertNotNull(package2);

    assertNull(package2.getApiClass("test.apicontainer.NonApiClass"));
    assertNotNull(package1.getApiClass("java.lang.Object"));
    assertNotNull(package2.getApiClass("test.apicontainer.ApiClass"));
    assertNotNull(package2.getApiClass("test.apicontainer.NonApiClass.ApiClassInNonApiClass"));
    assertNotNull(package2.getApiClass("test.apicontainer.NonApiClass.AnotherApiClassInNonApiClass"));
    assertEquals(1, package1.getApiClassNames().size());
    assertEquals(4, package2.getApiClassNames().size());
  }

  /**
   * Since constructors and methods use the same code, check methods in most
   * cases. Also need to check apiFields.
   * 
   * For methods, check if: (a) inherited methods are identified correctly as
   * apiMethods, (b) method overloading is done correctly
   * 
   */
  void checkApiMembers() {
    ApiClass object = apiCheck.getApiPackage("java.lang").getApiClass(
        "java.lang.Object");
    ApiClass apiClass = apiCheck.getApiPackage("test.apicontainer").getApiClass(
        "test.apicontainer.ApiClass");
    ApiClass innerClass = apiCheck.getApiPackage("test.apicontainer").getApiClass(
        "test.apicontainer.NonApiClass.ApiClassInNonApiClass");
    ApiClass oneMoreApiClass = apiCheck.getApiPackage("test.apicontainer").getApiClass(
        "test.apicontainer.OneMoreApiClass");

    // constructors
    assertEquals(1, innerClass.getApiMemberNames(
        ApiClass.MethodType.CONSTRUCTOR).size());

    // fields
    assertEquals(3, object.getApiFieldNames().size());
    assertEquals(4, apiClass.getApiFieldNames().size());
    assertEquals(3, oneMoreApiClass.getApiFieldNames().size());

    // methods
    assertEquals(4, object.getApiMemberNames(ApiClass.MethodType.METHOD).size());
    assertEquals(7,
        apiClass.getApiMemberNames(ApiClass.MethodType.METHOD).size());
    // the method definition lowest in the class hierarchy is kept
    assertNotSame(getMethodByName("apiMethod0", apiClass), getMethodByName(
        "apiMethod0", object));
    assertEquals(getMethodByName("protectedMethod0", apiClass),
        getMethodByName("protectedMethod0", object));
    assertNotNull(getMethodByName("methodInNonApiClass1", apiClass));

    assertEquals(5, oneMoreApiClass.getApiMemberNames(
        ApiClass.MethodType.METHOD).size());
    Set<String> methodNames = new HashSet<String>(
        Arrays.asList(new String[] {"checkOverloadedAndOverridableDetection1"}));
    assertEquals(1, oneMoreApiClass.getApiMembersBySet(methodNames,
        ApiClass.MethodType.METHOD).size());

    // checkOverloadedMethodAccounted should appear twice.
    methodNames = new HashSet<String>(
        Arrays.asList(new String[] {"checkOverloadedMethodAccounted1"}));
    assertEquals(2, oneMoreApiClass.getApiMembersBySet(methodNames,
        ApiClass.MethodType.METHOD).size());
  }

  /**
   * Test if apiPackages are identified correctly.
   */
  void checkApiPackages() {
    assertNotNull(apiCheck.getApiPackage("java.lang"));
    assertNotNull(apiCheck.getApiPackage("test.apicontainer"));
    assertEquals(3, apiCheck.getApiPackageNames().size());
  }
}
