/*
 * Copyright 2010 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.impl;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.js.JsniMethodBody;

/**
 * Test for {@link Pruner}.
 */
public class PrunerTest extends OptimizerTestBase {
  @Override
  protected void setUp() throws Exception {
    super.setUp();
    runDeadCodeElimination = true;
  }

  public void testSmoke() throws Exception {
    addSnippetClassDecl("static int foo(int i) { return i; }");

    addSnippetClassDecl("static void unusedMethod() { }");
    addSnippetClassDecl("static void usedMethod() { }");
    addSnippetClassDecl("static class UnusedClass { }");
    addSnippetClassDecl("static class UninstantiatedClass { "
        + "int field; native int method() /*-{ return 1; }-*/; }");
    addSnippetClassDecl("static UninstantiatedClass uninstantiatedField;");
    addSnippetClassDecl("static int unusedField;");
    addSnippetClassDecl("static int unreadField;");
    addSnippetClassDecl("static int unassignedField;");
    addSnippetClassDecl("static UninstantiatedClass returnUninstantiatedClass() { return null; }");
    addSnippetClassDecl(
        "interface UsedInterface {",
        "  int unusedConstant = 2;",
        "  int usedConstant = 3;",
        "  void method2();",
        "}");
    addSnippetClassDecl("static class UsedClass implements UsedInterface {",
        "  int field2;",
        "  public void method2() { field2 = usedConstant; }",
        "  UsedClass(UninstantiatedClass c) { }",
        "  UsedClass(UninstantiatedClass c1, UninstantiatedClass c2) { }",
        "  UsedClass(UninstantiatedClass c1, int i, UninstantiatedClass c2) { field2 = i; }",
        "  UsedClass(UninstantiatedClass c1, int i, UninstantiatedClass c2, int j) " +
            "{ field2 = i + j; }",
        "}");
    addSnippetClassDecl(
        "static native void usedNativeMethod(UninstantiatedClass c, UsedClass c2)",
        "/*-{",
        "  c.@test.EntryPoint.UninstantiatedClass::field = 2;",
        "  c.@test.EntryPoint.UninstantiatedClass::method();",
        "  c2.@test.EntryPoint.UsedClass::field2++;",
        "  c2.@test.EntryPoint.UsedClass::method2();",
        "}-*/;");
    addSnippetClassDecl(
        "static native void unusedNativeMethod()",
        "/*-{",
        "}-*/;");
    addSnippetClassDecl("static void methodWithUninstantiatedParam(UninstantiatedClass c) { }");
    addSnippetClassDecl("interface UnusedInterface { void foo(); }");
    addSnippetClassDecl("interface Callback { void go(); }");
    addSnippetImport("jsinterop.annotations.JsType");
    addSnippetImport("jsinterop.annotations.JsConstructor");
    addSnippetClassDecl("@JsType interface Js { void doIt(Callback cb); }");
    addSnippetClassDecl("@JsType(isNative=true) static class JsProto { ",
        "public JsProto(int arg) {}",
        "}");
    addSnippetClassDecl("static class JsProtoImpl extends JsProto {",
        "public JsProtoImpl() { super(10); }",
        "}");

    addSnippetClassDecl("static class JsProtoImpl2 extends JsProto {",
        "@JsConstructor public JsProtoImpl2() { super(10); }",
        "}");

    addSnippetClassDecl("static class JsProtoImpl3 extends JsProto {",
        "public JsProtoImpl3() { super(10); }",
        "}");

    Result result;
    (result = optimize("void",
        "usedMethod();",
        "unreadField = 1;",  // should be pruned because it's not read.
        "foo(unassignedField);",
        "returnUninstantiatedClass();",
        "usedNativeMethod(null, null);",
        "foo(uninstantiatedField.field);",
        "uninstantiatedField.method();",
        "methodWithUninstantiatedParam(null);",
        "new UsedClass(null);",
        "new UsedClass(returnUninstantiatedClass(), returnUninstantiatedClass());",
        "new UsedClass(returnUninstantiatedClass(), 3, returnUninstantiatedClass());",
        "new UsedClass(returnUninstantiatedClass(), 3, returnUninstantiatedClass(), 4);",
        "UninstantiatedClass localUninstantiated = null;",
        "JsProtoImpl jsp = new JsProtoImpl();"
        )).intoString(
            "EntryPoint.usedMethod();",
            "EntryPoint.foo(EntryPoint.unassignedField);",
            "EntryPoint.returnUninstantiatedClass();",
            "EntryPoint.usedNativeMethod(null, null);",
            "EntryPoint.foo(null.nullField);",
            "null.nullMethod();",
            "EntryPoint.methodWithUninstantiatedParam();",
            "new EntryPoint$UsedClass();",
            "EntryPoint.returnUninstantiatedClass();",
            "EntryPoint.returnUninstantiatedClass();",
            "new EntryPoint$UsedClass();",
            "int lastArg;",
            "new EntryPoint$UsedClass((lastArg = (EntryPoint.returnUninstantiatedClass(), 3), EntryPoint.returnUninstantiatedClass(), lastArg));",
            "new EntryPoint$UsedClass((EntryPoint.returnUninstantiatedClass(), 3), (EntryPoint.returnUninstantiatedClass(), 4));",
            "new EntryPoint$JsProtoImpl();"
            );

    assertNotNull(result.findMethod("usedMethod"));
    // We do not assign to the field, but we use its default value.
    // Shouldn't be pruned.
    assertNotNull(result.findField("unassignedField"));
    assertNotNull(result.findMethod("usedNativeMethod"));
    assertNotNull(result.findMethod("returnUninstantiatedClass"));
    assertNotNull(result.findMethod("methodWithUninstantiatedParam"));
    assertNotNull(result.findClass("EntryPoint$UsedClass"));
    assertNotNull(result.findClass("EntryPoint$UsedInterface"));

    assertNull(result.findMethod("unusedMethod"));
    assertNull(result.findField("unusedField"));
    assertNull(result.findField("unreadField"));
    assertNull(result.findClass("EntryPoint$UnusedClass"));
    assertNull(result.findMethod("unusedNativeMethod"));
    assertNull(result.findField("uninstantiatedField"));
    assertNull(result.findClass("EntryPoint$UnusedInterface"));

    // Class is never instantiated. Should be pruned.
    assertNull(result.findClass("UninstantiatedClass"));

    assertEquals(
        "static null returnUninstantiatedClass(){\n" +
        "  return null;\n" +
        "}",
        result.findMethod("returnUninstantiatedClass").toSource());

    assertEquals(
        "static void methodWithUninstantiatedParam(){\n" +
        "}",
        result.findMethod("methodWithUninstantiatedParam").toSource());

    assertEquals(
        "[final null nullField, int field2]",
        ((JsniMethodBody) result.findMethod("usedNativeMethod").getBody())
            .getJsniFieldRefs().toString());
    assertEquals(
        "[public final null nullMethod(), public void method2()]",
        ((JsniMethodBody) result.findMethod("usedNativeMethod").getBody())
            .getJsniMethodRefs().toString());

    assertEquals(
        "interface EntryPoint$UsedInterface {\n" +
        "  final static int usedConstant\n\n" +
        "  private static final void $clinit(){\n" +
        "    final static int usedConstant = 3;\n" +
        "  }\n" +
        "\n" +
        "}",
        result.findClass("EntryPoint$UsedInterface").toSource());

    // Neither super ctor call, nor super call's param is pruned
    assertEquals(
        "public EntryPoint$JsProtoImpl(){\n" +
            "  this.EntryPoint$JsProto.EntryPoint$JsProto(10);\n" +
            "  this.$init();\n" +
            "}",
        findMethod(result.findClass("EntryPoint$JsProtoImpl"), "EntryPoint$JsProtoImpl").toSource());

    // Not JsType'd, and not instantiated, so should be pruned
    assertNull(result.findClass("EntryPoint$JsProtoImpl3"));

    // Should be rescued because of @JsType
    assertNotNull(result.findClass("EntryPoint$JsProtoImpl2"));
  }

  public void testCleanupVariableOfNonReferencedType() throws Exception {
    runDeadCodeElimination = false;
    addSnippetClassDecl("static class A {}");
    addSnippetClassDecl("static boolean fun(A a) { return a == null; }");
    Result result = optimize("void", "fun(null);");
    assertNull(result.findClass("EntryPoint$A"));
    assertEquals("test.EntryPoint.fun(Ltest/EntryPoint$A;)Z", result.findMethod("fun").toString());
    assertTrue(result.findMethod("fun").getParams().get(0).getType().isNullType());
  }

  /**
   * Test for issue 2478.
   */
  public void testPrunerThenEqualityNormalizer() throws Exception {
    runDeadCodeElimination = false;
    addSnippetClassDecl("static int foo(int i) { return i; }");

    addSnippetClassDecl("static class UninstantiatedClass { "
        + "int field[]; native int method() /*-{ return 1; }-*/; }");
    addSnippetClassDecl("static UninstantiatedClass uninstantiatedField;");
    Result result;
    (result = optimize("int",
        "int i = 0;",
        "if (uninstantiatedField.field[i] == 0) { i = 2; }",
        "return i;"
    )).intoString(
        "int i = 0;",
        "if (null.nullField[i] == 0) {",
        "  i = 2;",
        "}",
        "return i;"
    );

    EqualityNormalizer.exec(result.getOptimizedProgram());
  }

  public void testInterface() throws Exception {
    runDeadCodeElimination = false;
    addSnippetClassDecl("interface I { int bar(); }");
    addSnippetClassDecl("static class A implements I { public int bar() { return 1; } }");
    Result result =
        optimize("void", "A a = new A(); a.bar();");
    assertNotNull(result.findClass("EntryPoint$I"));
    assertNotNull(result.findClass("EntryPoint$A"));
    assertNotNull(OptimizerTestBase.findMethod(result.findClass("EntryPoint$A"), "bar"));
    assertNull(OptimizerTestBase.findMethod(result.findClass("EntryPoint$I"), "bar"));
  }

  public void testDefaultInterface() throws Exception {
    runDeadCodeElimination = false;
    addSnippetClassDecl("interface I {default int bar() {return 1;} "
        + "default int foo() {return 1;} }");
    addSnippetClassDecl("static class A implements I { }");
    addSnippetClassDecl("interface I2 {default int foo() {return fun();}"
        + "default int fun() {return 1;}"
        + "default int goo() {return 0;}"
        + "static int s1() { return s2();}"
        + "static int s2() { return 0;}"
        + "static int s3() { return 1;}"
        + "}");
    Result result = optimize("void", "A a = new A(); a.bar(); "
        + "I2 i = new I2() {}; i.foo(); I2.s1();");
    assertNotNull(result.findClass("EntryPoint$A"));
    assertNotNull(result.findClass("EntryPoint$I"));
    assertNotNull(result.findClass("EntryPoint$I2"));
    assertNotNull(OptimizerTestBase.findMethod(result.findClass("EntryPoint$I"), "bar"));
    assertNotNull(OptimizerTestBase.findMethod(result.findClass("EntryPoint$A"), "bar"));
    assertNull(OptimizerTestBase.findMethod(result.findClass("EntryPoint$I"), "foo"));
    assertNotNull(OptimizerTestBase.findMethod(result.findClass("EntryPoint$I2"), "foo"));
    assertNotNull(OptimizerTestBase.findMethod(result.findClass("EntryPoint$I2"), "fun"));
    assertNull(OptimizerTestBase.findMethod(result.findClass("EntryPoint$I2"), "goo"));
    assertNotNull(OptimizerTestBase.findMethod(result.findClass("EntryPoint$I2"), "s1"));
    assertNotNull(OptimizerTestBase.findMethod(result.findClass("EntryPoint$I2"), "s2"));
    assertNull(OptimizerTestBase.findMethod(result.findClass("EntryPoint$I2"), "s3"));
  }

  public void testPruneParamsAndLocalsInMethodBody() throws Exception {
    runDeadCodeElimination = false;
    addSnippetClassDecl("interface I {default int bar() {int a = 0; return 1;} "
        + "static int fun(int b) {int a = 0; return 1;} }");
    Result result = optimize("void", "I i = new I() {}; i.bar(); I.fun(0);");
    assertNotNull(result.findClass("EntryPoint$I"));
    JMethod bar = OptimizerTestBase.findMethod(result.findClass("EntryPoint$I"), "bar");
    assertNotNull(bar);
    assertEquals("public int bar(){\n" +
        "  0;\n" +
        "  return 1;\n" +
        "}", bar.toSource());
    JMethod fun = OptimizerTestBase.findMethod(result.findClass("EntryPoint$I"), "fun");
    assertNotNull(fun);
    assertEquals("public static int fun(){\n" +
        "  0;\n" +
        "  return 1;\n" +
        "}", fun.toSource());
  }

  public void testJsFunction_notPruneUnusedJsFunction() throws Exception {
    addSnippetImport("jsinterop.annotations.JsFunction");
    addSnippetClassDecl(
        "@JsFunction interface MyJsFunctionInterface {",
        "int foo (int a);",
        "}");
    addSnippetClassDecl(
        "interface MyPlainInterface {",
        "int foo (int a);",
        "}");
    addSnippetClassDecl(
        "@JsFunction interface MyJsFunctionInterfaceUnused {",
        "int foo (int a);",
        "}");
    Result result;
    (result = optimize("void",
        "MyJsFunctionInterface a = new MyJsFunctionInterface() {"
            + "@Override public int foo (int a) { return 1; }"
            + "};"
            + "MyPlainInterface b = new MyPlainInterface() {"
            + "@Override public int foo (int a) { return 1; }"
            + "};"
        )).intoString(
            "new EntryPoint$1();\n" +
            "new EntryPoint$2();"
            );

    assertNotNull(result.findClass("EntryPoint$MyJsFunctionInterface"));
    assertNotNull(result.findClass("EntryPoint$MyPlainInterface"));
    assertNotNull(result.findClass("EntryPoint$MyJsFunctionInterfaceUnused"));

    // Function in JsFunction interface may be implicitly called in JS, should not be pruned.
    assertNotNull(OptimizerTestBase.findMethod(result.findClass("EntryPoint$1"), "foo"));
    assertNull(OptimizerTestBase.findMethod(result.findClass("EntryPoint$2"), "foo"));
  }

  public void testJsFunction_unrelatedjsFunctionCast() throws Exception {
    addSnippetImport("jsinterop.annotations.JsFunction");
    addSnippetClassDecl(
        "@JsFunction interface MyJsFunctionInterface {",
        "int foo (int a);",
        "}");
    addSnippetClassDecl(
        "@JsFunction interface MyOtherJsFunctionInterface {",
        "int bar (int a);",
        "}");
    addSnippetClassDecl(
        "interface MyPlainInterface {",
        "int goo (int a);",
        "}");
    Result result;
    (result = optimize("int",
        "MyJsFunctionInterface a = new MyJsFunctionInterface() {"
            + "@Override public int foo (int a) { return 1; }"
            + "};"
            + "return ((MyOtherJsFunctionInterface) a).bar(0) + ((MyPlainInterface) a).goo(0);"
        )).intoString(
            "EntryPoint$MyJsFunctionInterface a = new EntryPoint$1();\n" +
            "return ((EntryPoint$MyOtherJsFunctionInterface) a).bar(0) +" // SAM is not pruned.
            + " ((EntryPoint$MyPlainInterface) a).nullMethod();"
            );

    // JsFunction can be cross casted, or casted from JavaScript function
    // so the JsFunction interface and its SAM function should not be pruned.
    assertNotNull(result.findClass("EntryPoint$MyOtherJsFunctionInterface"));
    assertNotNull(OptimizerTestBase.findMethod(
        result.findClass("EntryPoint$MyOtherJsFunctionInterface"), "bar"));
    assertNull(result.findClass("EntryPoint$MyPlainInterface"));
 }

  @Override
  protected boolean doOptimizeMethod(TreeLogger logger, JProgram program, JMethod method) {
    program.addEntryMethod(findMainMethod(program));
    boolean didChange = false;
    // TODO(jbrosenberg): remove loop when Pruner/CFA interaction is perfect.
    while (Pruner.exec(program, true).didChange()) {
      didChange = true;
    }
    return didChange;
  }
}
