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

import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.javac.testing.impl.MockJavaResource;
import com.google.gwt.dev.jjs.ast.JField;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JNode;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JType;
import com.google.gwt.dev.util.Empty;
import com.google.gwt.thirdparty.guava.common.base.Joiner;
import com.google.gwt.thirdparty.guava.common.collect.Sets;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

/**
 * Tests {@link ControlFlowAnalyzer}.
 */
public class ControlFlowAnalyzerTest extends JJSTestBase {

  /**
   * Answers predicates about an analyzed program.
   */
  private static final class Result {
    private final ControlFlowAnalyzer cfa;
    private final JProgram program;

    public Result(JProgram program, ControlFlowAnalyzer cfa) {
      this.program = program;
      this.cfa = cfa;
    }

    public void assertOnlyFieldsWritten(String... expectedFields) {
      Set<JField> expectedSet = new HashSet<JField>();
      for (String expectedField : expectedFields) {
        JField field = findField(program, expectedField);
        assertNotNull(field);
        expectedSet.add(field);
      }
      assertEquals(expectedSet, cfa.getFieldsWritten());
    }

    public void assertOnlyInstantiatedTypes(String... expectedTypes) {
      Set<JType> expectedSet = Sets.newHashSet();
      for (String expectedType : expectedTypes) {
        JType type = findType(program, expectedType);
        assertNotNull(type);
        expectedSet.add(type);
      }
      assertEquals(expectedSet, cfa.getInstantiatedTypes());
    }

    public void assertOnlyLiveFieldsAndMethods(String... expected) {
      Set<JNode> expectedSet = new HashSet<JNode>();
      for (String expectedRef : expected) {
        JField field = findField(program, expectedRef);
        if (field != null) {
          expectedSet.add(field);
        } else {
          JMethod method = findQualifiedMethod(program, expectedRef);
          assertNotNull(method);
          expectedSet.add(method);
        }
      }
      assertEquals(expectedSet, cfa.getLiveFieldsAndMethods());
    }

    public void assertOnlyLiveStrings(String... expectedStrings) {
      Set<String> expectedSet = new HashSet<String>();
      Collections.addAll(expectedSet, expectedStrings);
      cfa.getLiveStrings();
      assertEquals(expectedSet, cfa.getLiveStrings());
    }
  }

  /**
   * Tests properties of an empty program.
   */
  public void testEmpty() throws Exception {
    Result result = analyzeSnippet("");
    result.assertOnlyFieldsWritten(Empty.STRINGS);
    result.assertOnlyInstantiatedTypes(Empty.STRINGS);
    result.assertOnlyLiveStrings(Empty.STRINGS);
  }

  /**
   * Tests that the JavaScriptObject type gets rescued in the three specific
   * circumstances where values can pass from JS into Java.
   */
  public void testRescueJavaScriptObjectFromJsni() throws Exception {
      sourceOracle.addOrReplace(new MockJavaResource("test.JsoIntf") {
      @Override
      public CharSequence getContent() {
        return Joiner.on("\n").join(
            "package test;",
            "import com.google.gwt.core.client.JavaScriptObject;",
            "public interface JsoIntf {",
            "  public int getAny();",
            "}");
      }
    });

      sourceOracle.addOrReplace(new MockJavaResource("test.UpRefIntf") {
      @Override
      public CharSequence getContent() {
        return Joiner.on("\n").join(
            "package test;",
            "import com.google.gwt.core.client.JavaScriptObject;",
            "public interface UpRefIntf {",
            "  public int getFoo();",
            "}");
      }
    });

     sourceOracle.addOrReplace(new MockJavaResource("test.NonImplementor") {
      @Override
      public CharSequence getContent() {
        return Joiner.on("\n").join(
            "package test;",
            "import com.google.gwt.core.client.JavaScriptObject;",
            "public class NonImplementor extends JavaScriptObject {",
            "  protected NonImplementor() {}",
            "  final public native int getFoo() /*-{ return 0; }-*/;",
            "}");
      }
    });

     sourceOracle.addOrReplace(new MockJavaResource("test.VirtualUpRef") {
      @Override
      public CharSequence getContent() {
        return Joiner.on("\n").join(
            "package test;",
            "import com.google.gwt.core.client.JavaScriptObject;",
            "final public class VirtualUpRef extends NonImplementor implements UpRefIntf {",
            "  protected VirtualUpRef() {}",
            "  public static native VirtualUpRef create() /*-{ return  {}; }-*/;",
            "}");
      }
    });

    sourceOracle.addOrReplace(new MockJavaResource("test.SingleJso") {
      @Override
      public CharSequence getContent() {
        return Joiner.on("\n").join(
            "package test;",
            "import com.google.gwt.core.client.JavaScriptObject;",
            "final public class SingleJso extends JavaScriptObject implements JsoIntf {",
            "  protected SingleJso() {}",
            "  public native int getAny() /*-{ return 1; }-*/;",
            "  public static native JsoIntf returnsJsoIntf() /*-{ return {}; }-*/;",
            "  public static native SingleJso returnsJso() /*-{ return {}; }-*/;",
            "}");
      }
    });

    sourceOracle.addOrReplace(new MockJavaResource("test.Foo") {
      @Override
      public CharSequence getContent() {
        return Joiner.on("\n").join(
            "package test;",
            "import com.google.gwt.core.client.JavaScriptObject;",
            "public class Foo {",
            "  public static native JavaScriptObject returnsJso() /*-{ return {}; }-*/;",
            "  public static native void assignsJsoField() /*-{ @test.Foo::jsoField = {}; }-*/;",
            "  public static native void readsJsoField() /*-{ var x = @test.Foo::jsoField; }-*/;",
            "  public static native void passesJsoParam() /*-{ @test.Foo::calledFromJsni(Lcom/google/gwt/core/client/JavaScriptObject;)({}); }-*/;",
            "  private static JavaScriptObject jsoField = null;",
            "  private static void calledFromJsni(JavaScriptObject arg) { }",
            "}");
      }
    });
    addSnippetImport("test.Foo");

    analyzeSnippet("").assertOnlyInstantiatedTypes(Empty.STRINGS);

    // Returning a JSO from a JSNI method rescues.
    analyzeSnippet("Foo.returnsJso();").assertOnlyInstantiatedTypes(
        "JavaScriptObject", "Object");

    // Assigning into a JSO field from a JSNI method rescues.
    analyzeSnippet("Foo.assignsJsoField();").assertOnlyInstantiatedTypes(
        "JavaScriptObject", "Object");

    // Passing from Java to JS via a JSNI field read should NOT rescue.
    analyzeSnippet("Foo.readsJsoField();").assertOnlyInstantiatedTypes(
        Empty.STRINGS);

    // Passing a parameter from JS to Java rescues.
    analyzeSnippet("Foo.passesJsoParam();").assertOnlyInstantiatedTypes(
        "JavaScriptObject", "Object");

    // Returning a JSO subType instantiates it
    analyzeSnippet("SingleJso.returnsJso();").assertOnlyInstantiatedTypes(
        "SingleJso", "JavaScriptObject", "Object", "JsoIntf");

    // Returning a JSO SingleJsoImpl instantiates it and the implementor
    analyzeSnippet("SingleJso.returnsJsoIntf();").assertOnlyInstantiatedTypes(
        "SingleJso", "JavaScriptObject", "Object", "JsoIntf");

    // A virtual upref should still be rescued
    analyzeSnippet("VirtualUpRef.create().getFoo();").assertOnlyInstantiatedTypes(
        "VirtualUpRef", "NonImplementor", "JavaScriptObject", "Object", "UpRefIntf");

    // and its methods
    analyzeSnippet("VirtualUpRef.create().getFoo();").assertOnlyLiveFieldsAndMethods(
        "VirtualUpRef.$clinit", "VirtualUpRef.create", "VirtualUpRef.getFoo",
        "NonImplementor.$clinit","NonImplementor.getFoo",
        "UpRefIntf.$clinit",
        "JavaScriptObject.$clinit",
        "EntryPoint.$clinit",
        "EntryPoint.onModuleLoad",
        "Object.$clinit");
  }

  /**
   * Tests that certain Java arrays are rescued if returned from JSNI code. Arrays that are rescued
   * if returned from JSNI: code whose leaf types are either primitive or types that might be
   * instantiated in JSNI.
   */
  public void testRescueArraysFromJSNI() throws Exception {
    sourceOracle.addOrReplace(new MockJavaResource("test.Foo") {
      @Override
      public CharSequence getContent() {
        return Joiner.on("\n").join(
            "package test;",
            "public class Foo {",
            "  public static native int[] create_array() /*-{ return {}; }-*/;",
            "  public static native int[][] create_2d_array() /*-{ return {}; }-*/;",
            "}");
      }
    });
    addSnippetImport("test.Foo");

    analyzeSnippet("").assertOnlyInstantiatedTypes(Empty.STRINGS);

    // Returning a JSO from a JSNI method rescues.
    analyzeSnippet("Foo.create_array();").assertOnlyInstantiatedTypes(
        "int[]", "Object");

    // Returning a JSO from a JSNI method rescues.
    analyzeSnippet("Foo.create_2d_array();").assertOnlyInstantiatedTypes(
        "int[][]", "Object[]", "Object");
  }

  private Result analyzeSnippet(String codeSnippet)
      throws UnableToCompleteException {
    JProgram program = compileSnippet("void", codeSnippet, true);
    ControlFlowAnalyzer cfa = new ControlFlowAnalyzer(program);
    cfa.traverseFrom(findMainMethod(program));
    return new Result(program, cfa);
  }
}
