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

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.junit.client.GWTTestCase;

/**
 * Tests {@link JavaScriptObject} and subclasses.
 */
public class JsoTest extends GWTTestCase {

  static class Bar extends JavaScriptObject {
    public static int field;

    public static native String staticNative() /*-{
      return "nativeBar";
    }-*/;

    public static String staticValue() {
      return "Bar" + field;
    }

    protected Bar() {
    }

    public final native String getBar() /*-{
      return this.bar;
    }-*/;

    public final String value() {
      return "Bar";
    }
  }

  static class Foo extends JavaScriptObject {
    public static int field;

    public static native String staticNative() /*-{
      return "nativeFoo";
    }-*/;
    
    /**
     * Ensure that a supertype can refer to members of a subtype.
     */
    public static native String staticNativeToSub() /*-{
      return @com.google.gwt.dev.jjs.test.JsoTest.FooSub::staticValueSub()();
    }-*/;

    public static String staticValue() {
      return "Foo" + field;
    }

    protected Foo() {
    }

    public final native String getFoo() /*-{
      return this.foo;
    }-*/;

    public final String value() {
      return "Foo";
    }
  }

  static class FooSub extends Foo {
    static String staticValueSub() {
      return "FooSub";
    }
    
    protected FooSub() {
    }

    public final String anotherValue() {
      return "Still Foo";
    }

    public final String superCall() {
      return super.value();
    }
  }

  static class JsArray<T> extends JavaScriptObject {
    public static native <T> JsArray<T> create() /*-{
      return [];
    }-*/;

    protected JsArray() {
    }

    public final native T get(int index) /*-{
      return this[index];
    }-*/;

    public final native int length() /*-{
      return this.length;
    }-*/;

    public final native void put(int index, T value) /*-{
      this[index] = value;
    }-*/;
  }

  static class MethodMangleClash {
    @SuppressWarnings("unused")
    public static String func(JavaScriptObject this_) {
      return "funcJavaScriptObject";
    }

    @SuppressWarnings("unused")
    public static String func(MethodMangleClash this_) {
      return "funcMethodMangleClash";
    }

    @SuppressWarnings("unused")
    public String func() {
      return "func";
    }
  }

  static class Overloads {
    private static volatile boolean FALSE = false;

    @SuppressWarnings("unused")
    static String sFunc(Bar b) {
      return "sFunc Bar";
    }

    @SuppressWarnings("unused")
    static String sFunc(Bar[][] b) {
      return "sFunc Bar[][]";
    }

    @SuppressWarnings("unused")
    static String sFunc(Foo f) {
      return "sFunc Foo";
    }

    @SuppressWarnings("unused")
    static String sFunc(Foo[][] f) {
      return "sFunc Foo[][]";
    }

    @SuppressWarnings("unused")
    public Overloads(Bar b) {
    }

    @SuppressWarnings("unused")
    public Overloads(Bar[][] b) {
    }

    @SuppressWarnings("unused")
    public Overloads(Foo f) {
    }

    @SuppressWarnings("unused")
    public Overloads(Foo[][] f) {
    }

    @SuppressWarnings("unused")
    String func(Bar b) {
      if (FALSE) {
        // prevent inlining
        return func(b);
      }
      return "func Bar";
    }

    @SuppressWarnings("unused")
    String func(Bar[][] b) {
      if (FALSE) {
        // prevent inlining
        return func(b);
      }
      return "func Bar[][]";
    }

    @SuppressWarnings("unused")
    String func(Foo f) {
      if (FALSE) {
        // prevent inlining
        return func(f);
      }
      return "func Foo";
    }

    @SuppressWarnings("unused")
    String func(Foo[][] f) {
      if (FALSE) {
        // prevent inlining
        return func(f);
      }
      return "func Foo[][]";
    }
  }

  private static native Bar makeBar() /*-{
    return {
      toString:function() {
        return "bar";
      },
      bar: "this is bar",
    };
  }-*/;

  private static native Foo makeFoo() /*-{
    return {
      toString:function() {
        return "foo";
      },
      foo: "this is foo",
    };
  }-*/;

  private static native JavaScriptObject makeJSO() /*-{
    return {
      toString:function() {
        return "jso";
      },
      foo: "jso foo",
      bar: "jso bar",
    };
  }-*/;

  private static native JavaScriptObject makeMixedArray() /*-{
    return [
      @com.google.gwt.dev.jjs.test.JsoTest::makeJSO()(),
      "foo",
      @com.google.gwt.dev.jjs.test.JsoTest::makeObject()(),
      null
    ];
  }-*/;

  private static Object makeObject() {
    return new Object() {
      @Override
      public String toString() {
        return "myObject";
      }
    };
  }

  private static native JavaScriptObject returnMe(JavaScriptObject jso) /*-{
    return jso;
  }-*/;

  @Override
  public String getModuleName() {
    return "com.google.gwt.dev.jjs.CompilerSuite";
  }

  public void testArrayInit() {
    Object[] array = {makeJSO(), new Object(), ""};
    assertTrue(array[0] instanceof JavaScriptObject);
    assertFalse(array[1] instanceof JavaScriptObject);
    assertFalse(array[2] instanceof JavaScriptObject);
  }

  public void testArrayStore() {
    JavaScriptObject[] jsoArray = new JavaScriptObject[1];
    jsoArray[0] = makeJSO();
    jsoArray[0] = makeFoo();
    jsoArray[0] = makeBar();

    Foo[] fooArray = new Foo[1];
    fooArray[0] = (Foo) makeJSO();
    fooArray[0] = makeFoo();
    fooArray[0] = makeBar().cast();

    Bar[] barArray = new Bar[1];
    barArray[0] = (Bar) makeJSO();
    barArray[0] = makeBar();
    barArray[0] = makeFoo().cast();

    Object[] objArray = jsoArray;
    try {
      objArray[0] = new Object();
      fail("Expected ArrayStoreException");
    } catch (ArrayStoreException expected) {
    }

    objArray = new Object[1];
    objArray[0] = makeJSO();
    objArray[0] = makeFoo();
    objArray[0] = makeBar();
  }

  public void testBasic() {
    JavaScriptObject jso = makeJSO();
    assertEquals("jso", jso.toString());

    Foo foo = (Foo) jso;
    assertEquals("jso", foo.toString());
    assertEquals("jso foo", foo.getFoo());
    assertEquals("Foo", foo.value());

    Bar bar = (Bar) jso;
    assertEquals("jso", bar.toString());
    assertEquals("jso bar", bar.getBar());
    assertEquals("Bar", bar.value());

    foo = makeFoo();
    assertEquals("foo", foo.toString());
    assertEquals("this is foo", foo.getFoo());
    assertEquals("Foo", foo.value());

    bar = makeBar();
    assertEquals("bar", bar.toString());
    assertEquals("this is bar", bar.getBar());
    assertEquals("Bar", bar.value());
  }

  @SuppressWarnings("cast")
  public void testCasts() {
    JavaScriptObject jso = makeJSO();
    assertTrue(jso instanceof JavaScriptObject);
    assertTrue(jso instanceof Foo);
    assertTrue(jso instanceof Bar);

    Foo foo = (Foo) jso;
    foo = makeFoo();
    assertTrue((JavaScriptObject) foo instanceof Bar);
    Bar bar = (Bar) (JavaScriptObject) makeFoo();
    bar = makeFoo().cast();

    bar = (Bar) jso;
    bar = makeBar();
    assertTrue((JavaScriptObject) bar instanceof Foo);
    foo = (Foo) (JavaScriptObject) makeBar();
    foo = makeBar().cast();

    // Implicit
    jso = foo;
    jso = bar;

    Object o = new Object();
    assertFalse(o instanceof JavaScriptObject);
    assertFalse(o instanceof Foo);
    assertFalse(o instanceof Bar);
    try {
      jso = (JavaScriptObject) o;
      fail("Expected ClassCastException");
    } catch (ClassCastException expected) {
    }

    o = "foo";
    assertFalse(o instanceof JavaScriptObject);
    assertFalse(o instanceof Foo);
    assertFalse(o instanceof Bar);
    try {
      jso = (JavaScriptObject) o;
      fail("Expected ClassCastException");
    } catch (ClassCastException expected) {
    }

    o = jso;
    assertFalse(o instanceof String);
    try {
      String s = (String) o;
      s = s.toString();
      fail("Expected ClassCastException");
    } catch (ClassCastException expected) {
    }
  }

  @SuppressWarnings("cast")
  public void testCastsArray() {
    JavaScriptObject[][] jso = new JavaScriptObject[0][0];
    assertTrue(jso instanceof JavaScriptObject[][]);
    assertTrue(jso instanceof Foo[][]);
    assertTrue(jso instanceof Bar[][]);

    Foo[][] foo = (Foo[][]) jso;
    foo = new Foo[0][0];
    assertTrue((JavaScriptObject[][]) foo instanceof Bar[][]);
    Bar[][] bar = (Bar[][]) (JavaScriptObject[][]) new Foo[0][0];

    bar = (Bar[][]) jso;
    bar = new Bar[0][0];
    assertTrue((JavaScriptObject[][]) bar instanceof Foo[][]);
    foo = (Foo[][]) (JavaScriptObject[][]) new Bar[0][0];

    Object[][] o = new Object[0][0];
    assertFalse(o instanceof JavaScriptObject[][]);
    assertFalse(o instanceof Foo[][]);
    assertFalse(o instanceof Bar[][]);
    try {
      jso = (JavaScriptObject[][]) o;
      fail("Expected ClassCastException");
    } catch (ClassCastException expected) {
    }

    o = jso;
    assertFalse(o instanceof String[][]);
    try {
      String[][] s = (String[][]) o;
      s.toString();
      fail("Expected ClassCastException");
    } catch (ClassCastException expected) {
    }
  }

  public void testClassLiterals() {
    JavaScriptObject jso = makeJSO();
    Foo foo = makeFoo();
    Bar bar = makeBar();
    assertEquals(JavaScriptObject.class, jso.getClass());
    assertEquals(Foo.class, jso.getClass());
    assertEquals(Bar.class, jso.getClass());
    assertEquals(JavaScriptObject.class, foo.getClass());
    assertEquals(Foo.class, foo.getClass());
    assertEquals(Bar.class, foo.getClass());
    assertEquals(JavaScriptObject.class, bar.getClass());
    assertEquals(Foo.class, bar.getClass());
    assertEquals(Bar.class, bar.getClass());
    assertEquals(JavaScriptObject.class, Foo.class);
    assertEquals(JavaScriptObject.class, Bar.class);
    assertEquals(Foo.class, Bar.class);

    if (!JavaScriptObject.class.getName().startsWith("Class$")) {
      // Class metadata could be disabled
      assertEquals("com.google.gwt.core.client.JavaScriptObject$",
          JavaScriptObject.class.getName());
    }
  }

  public void testClassLiteralsArray() {
    JavaScriptObject[][] jso = new JavaScriptObject[0][0];
    Foo[][] foo = new Foo[0][0];
    Bar[][] bar = new Bar[0][0];
    assertEquals(JavaScriptObject[][].class, jso.getClass());
    assertEquals(Foo[][].class, jso.getClass());
    assertEquals(Bar[][].class, jso.getClass());
    assertEquals(JavaScriptObject[][].class, foo.getClass());
    assertEquals(Foo[][].class, foo.getClass());
    assertEquals(Bar[][].class, foo.getClass());
    assertEquals(JavaScriptObject[][].class, bar.getClass());
    assertEquals(Foo[][].class, bar.getClass());
    assertEquals(Bar[][].class, bar.getClass());
    assertEquals(JavaScriptObject[][].class, Foo[][].class);
    assertEquals(JavaScriptObject[][].class, Bar[][].class);
    assertEquals(Foo[][].class, Bar[][].class);

    if (!JavaScriptObject.class.getName().startsWith("Class$")) {
      // Class metadata could be disabled
      assertEquals("[[Lcom.google.gwt.core.client.JavaScriptObject$;",
          JavaScriptObject[][].class.getName());
    }
  }

  public void testEquality() {
    JavaScriptObject jso = makeJSO();
    assertEquals(jso, jso);

    JavaScriptObject jso2 = makeJSO();
    assertFalse(jso.equals(jso2));
    assertFalse(jso2.equals(jso));

    jso2 = returnMe(jso);
    assertEquals(jso, jso2);
  }

  public void testGenericsJsos() {
    JsArray<JavaScriptObject> a = JsArray.create();
    a.put(0, makeJSO());
    a.put(1, makeFoo());
    a.put(2, makeBar());
    a.put(3, null);
    assertEquals(4, a.length());
    assertEquals("jso", a.get(0).toString());
    assertEquals("foo", a.get(1).toString());
    assertEquals("bar", a.get(2).toString());
    assertEquals(null, a.get(3));
  }

  public void testGenericsMixed() {
    JsArray<Object> a = JsArray.create();
    a.put(0, makeJSO());
    a.put(1, "foo");
    a.put(2, makeObject());
    a.put(3, null);
    assertEquals(4, a.length());
    assertEquals("jso", a.get(0).toString());
    assertEquals("foo", a.get(1));
    assertEquals("myObject", a.get(2).toString());
    assertEquals(null, a.get(3));
  }

  @SuppressWarnings("unchecked")
  public void testGenericsRawJson() {
    JsArray a = (JsArray) makeMixedArray();
    assertEquals(4, a.length());
    assertEquals("jso", a.get(0).toString());
    assertEquals("foo", a.get(1));
    assertEquals("myObject", a.get(2).toString());
    assertEquals(null, a.get(3));
  }

  public void testGenericsStrings() {
    JsArray<String> a = JsArray.create();
    a.put(0, "foo");
    a.put(1, "bar");
    a.put(2, "baz");
    a.put(3, null);
    assertEquals(4, a.length());
    assertEquals("foo", a.get(0));
    assertEquals("bar", a.get(1));
    assertEquals("baz", a.get(2));
    assertEquals(null, a.get(3));
  }

  public void testHashCode() {
    // TODO: make this better.
    JavaScriptObject jso = makeJSO();
    int jsoHashCode = jso.hashCode();
    Foo foo = makeFoo();
    Bar bar = makeBar();
    Object o = new Object() {
      @Override
      public int hashCode() {
        // Return something unlikely so as not to collide with the JSOs.
        return 0xDEADBEEF;
      }
    };

    assertEquals(jsoHashCode, jso.hashCode());
    assertFalse(jsoHashCode == foo.hashCode());
    assertFalse(jsoHashCode == bar.hashCode());
    assertFalse(jsoHashCode == o.hashCode());
    assertFalse(foo.hashCode() == bar.hashCode());
    assertFalse(foo.hashCode() == o.hashCode());
    assertFalse(bar.hashCode() == o.hashCode());

    o = jso;
    assertEquals(jsoHashCode, o.hashCode());

    String s = "foo";
    int stringHashCode = s.hashCode();
    o = s;
    assertEquals(stringHashCode, o.hashCode());
  }

  public void testIdentity() {
    JavaScriptObject jso = makeJSO();
    assertSame(jso, jso);

    JavaScriptObject jso2 = makeJSO();
    assertNotSame(jso, jso2);

    jso2 = returnMe(jso);
    assertSame(jso, jso2);
  }

  public void testInheritance() {
    Foo foo = makeFoo();
    FooSub fooSub = (FooSub) foo;
    assertEquals("Foo", fooSub.value());
    assertEquals("Still Foo", fooSub.anotherValue());
    assertEquals("Foo", fooSub.superCall());
  }

  public void testMethodMangleClash() {
    assertEquals("funcJavaScriptObject",
        MethodMangleClash.func((JavaScriptObject) null));
    assertEquals("funcMethodMangleClash",
        MethodMangleClash.func((MethodMangleClash) null));
    assertEquals("func", new MethodMangleClash().func());
  }

  public void testOverloads() {
    Foo foo = makeFoo();
    assertEquals("func Foo", new Overloads(foo).func(foo));
    assertEquals("sFunc Foo", Overloads.sFunc(foo));

    Bar bar = makeBar();
    assertEquals("func Bar", new Overloads(bar).func(bar));
    assertEquals("sFunc Bar", Overloads.sFunc(bar));
  }

  public void testOverloadsArray() {
    Foo[][] foo = new Foo[0][0];
    assertEquals("func Foo[][]", new Overloads(foo).func(foo));
    assertEquals("sFunc Foo[][]", Overloads.sFunc(foo));

    Bar[][] bar = new Bar[0][0];
    assertEquals("func Bar[][]", new Overloads(bar).func(bar));
    assertEquals("sFunc Bar[][]", Overloads.sFunc(bar));
  }

  public native void testOverloadsArrayNative() /*-{
    var o = @com.google.gwt.dev.jjs.test.JsoTest.Overloads::new([[Lcom/google/gwt/dev/jjs/test/JsoTest$Foo;)(null);
    @junit.framework.Assert::assertEquals(Ljava/lang/Object;Ljava/lang/Object;)("func Foo[][]", o.@com.google.gwt.dev.jjs.test.JsoTest.Overloads::func([[Lcom/google/gwt/dev/jjs/test/JsoTest$Foo;)(null));
    @junit.framework.Assert::assertEquals(Ljava/lang/Object;Ljava/lang/Object;)("sFunc Foo[][]", @com.google.gwt.dev.jjs.test.JsoTest.Overloads::sFunc([[Lcom/google/gwt/dev/jjs/test/JsoTest$Foo;)(null));

    var o = @com.google.gwt.dev.jjs.test.JsoTest.Overloads::new([[Lcom/google/gwt/dev/jjs/test/JsoTest$Bar;)(null);
    @junit.framework.Assert::assertEquals(Ljava/lang/Object;Ljava/lang/Object;)("func Bar[][]", o.@com.google.gwt.dev.jjs.test.JsoTest.Overloads::func([[Lcom/google/gwt/dev/jjs/test/JsoTest$Bar;)(null));
    @junit.framework.Assert::assertEquals(Ljava/lang/Object;Ljava/lang/Object;)("sFunc Bar[][]", @com.google.gwt.dev.jjs.test.JsoTest.Overloads::sFunc([[Lcom/google/gwt/dev/jjs/test/JsoTest$Bar;)(null));
  }-*/;

  public native void testOverloadsNative() /*-{
    var o = @com.google.gwt.dev.jjs.test.JsoTest.Overloads::new(Lcom/google/gwt/dev/jjs/test/JsoTest$Foo;)(null);
    @junit.framework.Assert::assertEquals(Ljava/lang/Object;Ljava/lang/Object;)("func Foo", o.@com.google.gwt.dev.jjs.test.JsoTest.Overloads::func(Lcom/google/gwt/dev/jjs/test/JsoTest$Foo;)(null));
    @junit.framework.Assert::assertEquals(Ljava/lang/Object;Ljava/lang/Object;)("sFunc Foo", @com.google.gwt.dev.jjs.test.JsoTest.Overloads::sFunc(Lcom/google/gwt/dev/jjs/test/JsoTest$Foo;)(null));

    var o = @com.google.gwt.dev.jjs.test.JsoTest.Overloads::new(Lcom/google/gwt/dev/jjs/test/JsoTest$Bar;)(null);
    @junit.framework.Assert::assertEquals(Ljava/lang/Object;Ljava/lang/Object;)("func Bar", o.@com.google.gwt.dev.jjs.test.JsoTest.Overloads::func(Lcom/google/gwt/dev/jjs/test/JsoTest$Bar;)(null));
    @junit.framework.Assert::assertEquals(Ljava/lang/Object;Ljava/lang/Object;)("sFunc Bar", @com.google.gwt.dev.jjs.test.JsoTest.Overloads::sFunc(Lcom/google/gwt/dev/jjs/test/JsoTest$Bar;)(null));
  }-*/;

  public void testStaticAccess() {
    Foo.field = 3;
    assertEquals(3, Foo.field--);
    assertEquals("Foo2", Foo.staticValue());
    assertEquals("nativeFoo", Foo.staticNative());
    assertEquals("FooSub", Foo.staticNativeToSub());

    Bar.field = 10;
    assertEquals(11, ++Bar.field);
    assertEquals("Bar11", Bar.staticValue());
    assertEquals("nativeBar", Bar.staticNative());
  }

  public native void testStaticAccessNative() /*-{
    @com.google.gwt.dev.jjs.test.JsoTest.Foo::field = 3;
    @junit.framework.Assert::assertEquals(II)(3, @com.google.gwt.dev.jjs.test.JsoTest.Foo::field--);
    @junit.framework.Assert::assertEquals(Ljava/lang/Object;Ljava/lang/Object;)("Foo2", @com.google.gwt.dev.jjs.test.JsoTest.Foo::staticValue()());
    @junit.framework.Assert::assertEquals(Ljava/lang/Object;Ljava/lang/Object;)("nativeFoo", @com.google.gwt.dev.jjs.test.JsoTest.Foo::staticNative()());

    @com.google.gwt.dev.jjs.test.JsoTest.Bar::field = 10;
    @junit.framework.Assert::assertEquals(II)(11, ++@com.google.gwt.dev.jjs.test.JsoTest.Bar::field);
    @junit.framework.Assert::assertEquals(Ljava/lang/Object;Ljava/lang/Object;)("Bar11", @com.google.gwt.dev.jjs.test.JsoTest.Bar::staticValue()());
    @junit.framework.Assert::assertEquals(Ljava/lang/Object;Ljava/lang/Object;)("nativeBar", @com.google.gwt.dev.jjs.test.JsoTest.Bar::staticNative()());
  }-*/;

  public void testStaticAccessSubclass() {
    FooSub.field = 3;
    assertEquals(3, FooSub.field--);
    assertEquals("Foo2", FooSub.staticValue());
    assertEquals("nativeFoo", FooSub.staticNative());
  }
}
