/*
 * 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.JavaScriptException;
import com.google.gwt.junit.client.GWTTestCase;

/**
 * This should probably be refactored at some point.
 */
public class MiscellaneousTest extends GWTTestCase {

  interface I {
  }

  interface IBar extends I {
  }

  interface IFoo extends I {
  }

  static class PolyA implements IFoo {
    public String toString() {
      return "A";
    }
  }

  static class PolyB implements IBar {
    public String toString() {
      return "B";
    }
  }

  private static class HasClinit {
    public static int i = 1;

    private static HasClinit sInstance = new HasClinit();

    public static int sfoo() {
      return sInstance.foo();
    }

    private static native void clinitInNative() /*-{
    }-*/;

    private int foo() {
      this.toString();
      return 3;
    }
  }

  private static volatile boolean FALSE = false;

  private static volatile boolean TRUE = true;

  private static void assertAllCanStore(Object[] dest, Object[] src) {
    for (int i = 0; i < src.length; ++i) {
      dest[0] = src[i];
    }
  }

  private static void assertNoneCanStore(Object[] dest, Object[] src) {
    for (int i = 0; i < src.length; ++i) {
      try {
        dest[0] = src[i];
        fail();
      } catch (ArrayStoreException e) {
      }
    }
  }

  private static native void clinitFromNative() /*-{
    @com.google.gwt.dev.jjs.test.MiscellaneousTest$HasClinit::i = 5;
  }-*/;

  private static native void noOp() /*-{
  }-*/;

  private static native void throwNativeException() /*-{
    var a; a.asdf();
  }-*/;

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

  public void testArrayCasts() {
    {
      // thwart optimizer
      Object f1 = FALSE ? (Object) new PolyA() : (Object) new IFoo[1];
      if (expectClassMetadata()) {
        assertEquals("[Lcom.google.gwt.dev.jjs.test.MiscellaneousTest$IFoo;",
            f1.getClass().getName());
      }
      assertFalse(f1 instanceof PolyA[][]);
      assertFalse(f1 instanceof IFoo[][]);
      assertFalse(f1 instanceof PolyA[]);
      assertTrue(f1 instanceof IFoo[]);
      assertFalse(f1 instanceof PolyA);
      assertFalse(f1 instanceof IFoo);
      assertTrue(f1 instanceof Object[]);
      assertFalse(f1 instanceof Object[][]);

      assertAllCanStore((Object[]) f1, new Object[] {new PolyA(), new IFoo() {
      }});
      assertNoneCanStore((Object[]) f1, new Object[] {
          new PolyB(), new Object(), new Object[0]});
    }

    {
      // thwart optimizer
      Object a1 = FALSE ? (Object) new PolyA() : (Object) new PolyA[1];
      if (expectClassMetadata()) {
        assertEquals("[Lcom.google.gwt.dev.jjs.test.MiscellaneousTest$PolyA;",
            a1.getClass().getName());
      }
      assertFalse(a1 instanceof PolyA[][]);
      assertFalse(a1 instanceof IFoo[][]);
      assertTrue(a1 instanceof PolyA[]);
      assertTrue(a1 instanceof IFoo[]);
      assertFalse(a1 instanceof PolyA);
      assertFalse(a1 instanceof IFoo);
      assertTrue(a1 instanceof Object[]);
      assertFalse(a1 instanceof Object[][]);

      assertAllCanStore((Object[]) a1, new Object[] {new PolyA()});
      assertNoneCanStore((Object[]) a1, new Object[] {new IFoo() {
      }, new PolyB(), new Object(), new Object[0]});
    }

    {
      // thwart optimizer
      Object f2 = FALSE ? (Object) new PolyA() : (Object) new IFoo[1][];
      if (expectClassMetadata()) {
        assertEquals("[[Lcom.google.gwt.dev.jjs.test.MiscellaneousTest$IFoo;",
            f2.getClass().getName());
      }
      assertFalse(f2 instanceof PolyA[][]);
      assertTrue(f2 instanceof IFoo[][]);
      assertFalse(f2 instanceof PolyA[]);
      assertFalse(f2 instanceof IFoo[]);
      assertFalse(f2 instanceof PolyA);
      assertFalse(f2 instanceof IFoo);
      assertTrue(f2 instanceof Object[]);
      assertTrue(f2 instanceof Object[][]);

      assertAllCanStore((Object[]) f2, new Object[] {new PolyA[0], new IFoo[0]});
      assertNoneCanStore((Object[]) f2, new Object[] {new IFoo() {
      }, new PolyB(), new Object(), new Object[0]});
    }

    {
      // thwart optimizer
      Object a2 = FALSE ? (Object) new PolyA() : (Object) new PolyA[1][];
      if (expectClassMetadata()) {
        assertEquals("[[Lcom.google.gwt.dev.jjs.test.MiscellaneousTest$PolyA;",
            a2.getClass().getName());
      }
      assertTrue(a2 instanceof PolyA[][]);
      assertTrue(a2 instanceof IFoo[][]);
      assertFalse(a2 instanceof PolyA[]);
      assertFalse(a2 instanceof IFoo[]);
      assertFalse(a2 instanceof PolyA);
      assertFalse(a2 instanceof IFoo);
      assertTrue(a2 instanceof Object[]);
      assertTrue(a2 instanceof Object[][]);

      assertAllCanStore((Object[]) a2, new Object[] {new PolyA[0]});
      assertNoneCanStore((Object[]) a2, new Object[] {new IFoo() {
      }, new PolyB(), new Object(), new Object[0], new IFoo[0]});
    }
  }

  public void testArrays() {
    int[] c = new int[] {1, 2};
    int[][] d = new int[][] { {1, 2}, {3, 4}};
    int[][][] e = new int[][][] { { {1, 2}, {3, 4}}, { {5, 6}, {7, 8}}};
    if (expectClassMetadata()) {
      assertEquals("[I", c.getClass().getName());
      assertEquals("[[I", d.getClass().getName());
      assertEquals("[I", d[1].getClass().getName());
      assertEquals("[[[I", e.getClass().getName());
      assertEquals("[[I", e[1].getClass().getName());
      assertEquals("[I", e[1][1].getClass().getName());
    }
    assertEquals(2, c[1]);
    assertEquals(3, d[1][0]);
    assertEquals(8, e[1][1][1]);

    int[][][] b = new int[3][2][1];
    b[2][1][0] = 1;
    b = new int[3][2][];
    b[2][1] = null;
    b = new int[3][][];
    b[2] = null;
  }

  public void testAssociativityCond() {
    int result = (TRUE ? TRUE : FALSE) ? 100 : 200;
    assertEquals(100, result);
  }

  @SuppressWarnings("cast")
  public void testCasts() {
    Object o = FALSE ? (Object) new PolyA() : (Object) new PolyB();
    assertTrue(o instanceof I);
    assertFalse(o instanceof IFoo);
    assertTrue(o instanceof IBar);
    assertFalse(o instanceof PolyA);
    assertTrue(o instanceof PolyB);
    try {
      o = (PolyA) o;
      fail();
    } catch (ClassCastException e) {
    }
  }

  public void testClinit() {
    ++HasClinit.i;
    HasClinit x = new HasClinit();
    ++x.i;
    new HasClinit().i++;
    HasClinit.i /= HasClinit.i;
    HasClinit.sfoo();
    HasClinit.i /= HasClinit.sfoo();
    HasClinit.clinitInNative();
    clinitFromNative();
  }

  public void testExceptions() {
    int i;
    for (i = 0; i < 5; ++i) {
      boolean hitOuter = false;
      boolean hitInner = false;
      try {
        try {
          switch (i) {
            case 0:
              throw new RuntimeException();
            case 1:
              throw new IndexOutOfBoundsException();
            case 2:
              throw new Exception();
            case 3:
              throw new StringIndexOutOfBoundsException();
            case 4:
              throwNativeException();
          }
        } catch (StringIndexOutOfBoundsException e) {
          assertEquals(3, i);
        } finally {
          hitInner = true;
        }
      } catch (IndexOutOfBoundsException f) {
        assertEquals(1, i);
      } catch (JavaScriptException js) {
        assertEquals(4, i);
      } catch (RuntimeException g) {
        assertEquals(0, i);
      } catch (Throwable e) {
        assertEquals(2, i);
      } finally {
        assertTrue(hitInner);
        hitOuter = true;
      }
      assertTrue(hitOuter);
    }
    assertEquals(5, i);
  }

  public void testIssue2479() {
    if (TRUE) {
      FALSE = false;
    } else if (FALSE) {
      TRUE = true;
    } else {
      noOp();
    }
  }

  public void testString() {
    String x = "hi";
    assertEquals("hi", x);
    assertEquals("hi", x.toString());
    x = new String();
    assertEquals("", x);
    x = new String(x);
    assertEquals("", x);
    x = new String("hi");
    assertEquals("hi", x);
    assertEquals('i', x.charAt(1));
    assertEquals("hiyay", x.concat("yay"));
    assertEquals("hihi", x + x);

    assertEquals(
        "blahcom.google.gwt.dev.jjs.test.MiscellaneousTestabctruefalsenullc27",
        ("blah" + this + String.valueOf(new char[] {'a', 'b', 'c'}) + true
            + false + null + 'c' + 27));
  }

  /**
   * Ensures that polymorphic dispatch to String works correctly.
   */
  @SuppressWarnings("unchecked")
  public void testStringPrototype() {
    Object s = FALSE ? new Object() : "Hello, World!";
    assertEquals(String.class, s.getClass());
    assertEquals("Hello, World!".hashCode(), s.hashCode());
    assertTrue(s.equals("Hello, World!"));
    assertTrue("Hello, World!".equals(s));
    assertFalse(s.equals(""));
    assertFalse("".equals(s));
    assertEquals("Hello, World!", s.toString());
    assertTrue(s instanceof String);

    Comparable b = FALSE ? new Integer(1) : "Hello, World!";
    assertTrue(((Comparable) "Hello, World!").compareTo(b) == 0);
    assertTrue(b.compareTo("Hello, World!") == 0);
    assertTrue(((Comparable) "A").compareTo(b) < 0);
    assertTrue(b.compareTo("A") > 0);
    assertTrue(((Comparable) "Z").compareTo(b) > 0);
    assertTrue(b.compareTo("Z") < 0);
    assertTrue(b instanceof String);

    CharSequence c = FALSE ? new StringBuffer() : "Hello, World!";
    assertEquals('e', c.charAt(1));
    assertEquals(13, c.length());
    assertEquals("ello", c.subSequence(1, 5));
    assertTrue(c instanceof String);
  }

  public String toString() {
    return "com.google.gwt.dev.jjs.test.MiscellaneousTest";
  }

  private boolean expectClassMetadata() {
    String name = Object.class.getName();

    if (name.equals("java.lang.Object")) {
      return true;
    } else if (name.startsWith("Class$")) {
      return false;
    }

    throw new RuntimeException("Unexpected class name " + name);
  }
}
