/*
 * 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.junit.client.GWTTestCase;

import java.util.Arrays;
import java.util.Iterator;

/**
 * This test is intended to exercise as many code paths and node types as
 * possible in the Java to JavaScript compiler. This test is not at all intended
 * to execute correctly.
 */
@SuppressWarnings("hiding")
public class CoverageTest extends CoverageBase {

  /**
   * TODO: document me.
   */
  public class Inner extends Super {

    public int x = 3;
    public final int y = 4;

    public Inner() {
      // ExplicitConstructorCall
      this(4);
    }

    public Inner(int i) {
      // ExplicitConstructorCall
      super(i);
    }

    @Override
    public void foo() {
      final int z = this.y;

      new Inner() {
        {
          x = z;
          this.x = z;
          Inner.this.x = z;
          next = CoverageTest.this.next;
          next.foo();
          CoverageTest.this.next.foo();
          CoverageTest.this.x = z;
          CoverageTest.super.x = z;
        }

        @Override
        public void foo() {
          x = z;
          this.x = z;
          Inner.this.x = z;
          next = CoverageTest.this.next;
          next.foo();
          CoverageTest.this.next.foo();
          CoverageTest.this.x = z;
          CoverageTest.super.x = z;
        }
      };

      class NamedLocal extends Inner {
        @Override
        @SuppressWarnings("unused")
        public void foo() {
          CoverageTest.this.getNext();
          Inner.this.bar();
          super.bar();
          int x = z;
        }

        // JDT bug? This works in 5.0 but not in 1.4
        // TODO: will javac compile it?
        class NamedLocalSub extends NamedLocal {
          @Override
          @SuppressWarnings("unused")
          public void foo() {
            Inner.this.bar();
            NamedLocal.this.foo();
            super.foo();
            int x = z;
          }
        }
      }
      testEmptyStatement();

      new InnerSub().new InnerSubSub().fda();
      new SecondMain().new FunkyInner();
      /*
       * The statement below causes a javac bug in openJdk and sun's java 6. It
       * produces incorrect bytecode that fails with a java.lang.VerifyError --
       * see Google's internal issue 1628473. This is likely to be an hindrance
       * if and when GWT attempts to read bytecode directly.
       */
      // new NamedLocal().new NamedLocalSub().foo();
    }

    public void bar() {
    }

    private void testAllocationExpression() {
      // AllocationExpression
      o = new Super();
      assertEquals("3", o.toString());
      o = new Super(42);
      assertEquals("42", o.toString());
    }

    private void testAndAndExpression() {
      // AND_AND_Expression
      i = 2;
      z = i == 1 && betterNotEval();
      assertFalse(z);
    }

    private void testArrayAllocationExpression() {
      // ArrayAllocationExpression
      ia = new int[4];
      assertEquals(4, ia.length);
      iaa = new int[4][3];
      assertEquals(4, iaa.length);
      assertEquals(3, iaa[2].length);
      iaaa = new int[4][3][];
      assertEquals(4, iaaa.length);
      assertEquals(3, iaaa[2].length);
      assertNull(iaaa[2][2]);
    }

    private void testArrayInitializer() {
      // ArrayInitializer
      ia = new int[] {i, j};
      assertEquals(2, ia.length);
      assertEquals(j, ia[1]);
      iaa = new int[][] {{i, j}};
      assertEquals(1, iaa.length);
      assertEquals(2, iaa[0].length);
      assertEquals(j, iaa[0][1]);
      iaa = new int[][] { {i, j}, ia};
      assertEquals(2, iaa.length);
      assertEquals(2, iaa[0].length);
      assertEquals(j, iaa[0][1]);
      assertEquals(ia, iaa[1]);
    }

    private void testArrayReference() {
      ia = new int[] {i, j};
      // ArrayReference
      i = ia[0];
      assertEquals(ia[0], i);
      ia[0] = i;
    }

    private void testAssertStatement() {
      // AssertStatement

      if (!CoverageTest.class.desiredAssertionStatus()) {
        return;
      }

      i = 1;
      try {
        assert i == 2;
        throw new Error();
      } catch (AssertionError e) {
      }

      try {
        assert i == 3 : true;
        fail();
      } catch (AssertionError e) {
        assertEquals("true", e.getMessage());
      }

      try {
        assert i == 3 : 'c';
        fail();
      } catch (AssertionError e) {
        assertEquals("c", e.getMessage());
      }

      try {
        assert i == 3 : 1.1;
        fail();
      } catch (AssertionError e) {
        assertEquals("1.1", e.getMessage());
      }

      try {
        assert i == 3 : 1.5f;
        fail();
      } catch (AssertionError e) {
        assertEquals("1.5", e.getMessage());
      }

      try {
        assert i == 3 : 5;
        fail();
      } catch (AssertionError e) {
        assertEquals("5", e.getMessage());
      }

      try {
        assert i == 3 : 6L;
        fail();
      } catch (AssertionError e) {
        assertEquals("6", e.getMessage());
      }

      try {
        assert i == 3 : "foo";
        fail();
      } catch (AssertionError e) {
        assertEquals("foo", e.getMessage());
      }

      try {
        assert i == 3 : new Object() {
          @Override
          public String toString() {
            return "bar";
          }
        };
        fail();
      } catch (AssertionError e) {
        assertEquals("bar", e.getMessage());
      }
    }

    private void testAssignment() {
      // Assignment
      i = j;
      assertEquals(j, i);
    }

    private void testBinaryExpression() {
      // BinaryExpression
      i = 4;
      i = i + j;
      assertEquals(6, i);
      i = i - j;
      assertEquals(4, i);
      i = i * j;
      assertEquals(8, i);
      i = i / j;
      assertEquals(4, i);
      i = i % j;
      assertEquals(0, i);
      i = 7;
      i = i & j;
      assertEquals(2, i);
      i = 0;
      i = i | j;
      assertEquals(2, i);
      i = 7;
      i = i ^ j;
      assertEquals(5, i);
      i = i << j;
      assertEquals(20, i);
      i = i >> j;
      assertEquals(5, i);
      i = i >>> j;
      assertEquals(1, i);
    }

    private void testBreakContinueLabelStatement() {
      // BreakStatement, ContinueStatement
      z = true;
      i = 0;
      x = 0;
      outer : while (z) {
        ++x;
        inner : while (z) {
          ++i;
          if (i == 1) {
            continue;
          }
          if (i == 2) {
            continue inner;
          }
          if (i == 3) {
            continue outer;
          }
          if (i == 4) {
            break;
          }
          if (i == 5) {
            break inner;
          }
          if (i == 6) {
            break outer;
          }
        }
      }
      assertEquals(6, i);
      assertEquals(4, x);
    }

    private void testCaseSwitchStatement() {
      // CaseStatement, SwitchStatement
      i = 6;
      switch (j) {
        case 1:
          ++i;
          // fallthrough
        case 2:
          i += 2;
          // fallthrough
        case 3:
          i += 3;
          // fallthrough
        case 4:
          i += 4;
          // fallthrough
        default:
          i += 0;
      }
      assertEquals(15, i);
    }

    @SuppressWarnings("cast")
    private void testCastExpression() {
      // CastExpression
      o = (Super) o;
    }

    private void testCharLiteral() {
      // CharLiteral
      i = 'c';
      assertEquals("c", String.valueOf((char) i));
    }

    private void testClassLiteralAccess() {
      // ClassLiteralAccess
      o = Super.class;
      String str = o.toString();

      // Class metadata could be disabled
      if (!str.startsWith("class Class$")) {
        assertEquals("class com.google.gwt.dev.jjs.test.CoverageTest$Super",
            str);
      }
    }

    private void testCompoundAssignment() {
      // CompoundAssignment
      i = 4;
      i += j;
      assertEquals(6, i);
      i -= j;
      assertEquals(4, i);
      i *= j;
      assertEquals(8, i);
      i /= j;
      assertEquals(4, i);
      i %= j;
      assertEquals(0, i);
      i = 7;
      i &= j;
      assertEquals(2, i);
      i = 0;
      i |= j;
      assertEquals(2, i);
      i = 7;
      i ^= j;
      assertEquals(5, i);
      i <<= j;
      assertEquals(20, i);
      i >>= j;
      assertEquals(5, i);
      i >>>= j;
      assertEquals(1, i);
    }

    private void testConditionalExpression() {
      // ConditionalExpression
      z = false;
      i = z ? 7 : j;
      assertEquals(j, i);
    }

    private void testDoStatement() {
      // DoStatement
      i = 3;
      z = false;
      do {
        i += j;
      } while (z);
      assertEquals(5, i);
    }

    private void testEmptyStatement() {
      // EmptyStatement
      ;
    }

    private void testEqualExpression() {
      // EqualExpression
      i = 3;
      assertFalse(i == j);
      assertTrue(i != j);
      assertFalse(i < j);
      assertFalse(i <= j);
      assertTrue(i > j);
      assertTrue(i >= j);
    }

    private void testForeachStatement() {
      ia = new int[] {i, j};
      // Array of primitive.
      for (int q : ia) {
        i = q;
      }
      // Array of primitive with unboxing.
      for (Integer q : ia) {
        i = q;
      }
      // Array of object.
      for (String str : sa) {
        s = str;
      }
      // Iterable.
      for (Object obj : Arrays.asList(new Object(), new Object())) {
        o = obj;
      }
      // Iterable with unboxing.
      for (int q : Arrays.asList(1, 2, 3)) {
        i = q;
      }
      // Iterable with generic cast.
      for (String str : Arrays.asList(sa)) {
        s = str;
      }
      // Iterable with array element.
      for (String[] stra : Arrays.asList(sa, sa, sa)) {
        s = sa[0];
      }
      // Iterable Iterator subclass.
      class SubIterator<T> implements Iterator<T> {
        private final Iterator<T> it;

        public SubIterator(Iterator<T> it) {
          this.it = it;
        }

        @Override
        public boolean hasNext() {
          return it.hasNext();
        }

        @Override
        public T next() {
          return it.next();
        }

        @Override
        public void remove() {
          it.remove();
        }
      }
      class SubIterableString implements Iterable<String> {
        @Override
        public SubIterator<String> iterator() {
          return new SubIterator<String>(Arrays.asList(sa).iterator());
        }
      }
      for (String str : new SubIterableString()) {
        s = str;
      }
    }

    private void testForStatement() {
      // ForStatement
      i = 0;
      for (int q = 0, v = 4; q < v; ++q) {
        i += q;
      }
      assertEquals(6, i);
      for (i = 0; i < 4; ++i) {
      }
      assertEquals(4, i);
    }

    private void testIfStatement() {
      // IfStatement
      z = false;
      if (z) {
        fail();
      }
      if (z) {
        fail();
      } else {
        assertFalse(z);
      }
      if (!z) {
        assertFalse(z);
      } else {
        fail();
      }
    }

    private void testInstanceOfExpression() {
      // InstanceOfExpression
      Object o = CoverageTest.this;
      assertTrue(o instanceof CoverageBase);
    }

    private void testLiterals() {
      // DoubleLiteral
      d = 3.141592653589793;
      assertEquals(3, (int) d);

      // FalseLiteral
      assertFalse(false);

      // FloatLiteral
      f = 3.1415927f;
      assertEquals(3, (int) f);

      // IntLiteral
      i = 4;

      // IntLiteralMinValue
      i = -2147483648;

      // LongLiteral
      l = 4L;

      // LongLiteralMinValue
      l = -9223372036854775808L;

      // NullLiteral
      o = null;

      // StringLiteral
      s = "f'oo\b\t\n\f\r\"\\";
      assertEquals(s, "f" + '\'' + 'o' + 'o' + '\b' + '\t' + '\n' + '\f' + '\r'
          + '"' + '\\');

      // TrueLiteral
      assertTrue(true);
    }

    private void testOrOrExpression() {
      // OR_OR_Expression
      i = 1;
      assertTrue(i == 1 || betterNotEval());
    }

    private void testPostfixExpression() {
      // PostfixExpression
      i = 1;
      assertEquals(1, i++);
      assertEquals(2, i--);
    }

    private void testPrefixExpression() {
      // PrefixExpression
      i = 1;
      assertEquals(2, ++i);
      assertEquals(1, --i);
    }

    private void testQualifiedAllocationExpression() {
      // QualifiedAllocationExpression
      o = new Inner();
      o = CoverageTest.this.new Inner();
      o = new CoverageTest().new Inner();
    }

    private void testQualifiedNameReference() {
      // QualifiedNameReference
      CoverageTest m = new CoverageTest();
      ia = new int[2];
      assertEquals("1", 2, ia.length);
      assertEquals("2", 2, m.j);
      assertEquals("3", 4, m.y);
      assertEquals("4", 2, new CoverageTest().j);
      assertEquals("5", 4, new CoverageTest().y);
      assertEquals("6", 2, m.next.j);
      assertEquals("7", 4, m.next.y);
      assertEquals("8", 2, new CoverageTest().next.j);
      assertEquals("9", 4, new CoverageTest().next.y);
      assertEquals("A", 2, m.getNext().j);
      assertEquals("B", 4, m.getNext().y);
      assertEquals("C", 2, new CoverageTest().getNext().j);
      assertEquals("D", 4, new CoverageTest().getNext().y);
    }

    private void testReferenceCalls() {
      // MessageSend, QualifiedSuperReference, QualifiedThisReference,
      // SuperReference, ThisReference
      Inner other = new Inner();
      foo();
      this.foo();
      other.foo();
      CoverageTest.this.foo();
      super.foo();
      Inner.super.foo();
      CoverageTest.super.foo();

      sfoo();
      this.sfoo();
      CoverageTest.sfoo();
      Inner.sfoo();
      Super.sfoo();
      other.sfoo();
      CoverageTest.this.sfoo();
      super.sfoo();
      Inner.super.sfoo();
      CoverageTest.super.sfoo();
    }

    private Inner testReferences() {
      // FieldReference, QualifiedSuperReference, QualifiedThisReference,
      // SuperReference, ThisReference
      Inner other = new Inner();
      i = 3;
      i = i + j + x + y;
      assertEquals(12, i);
      i = this.i + this.j + this.x + this.y;
      assertEquals(21, i);
      i = CoverageTest.i + CoverageTest.j;
      assertEquals(8, i);
      i = Inner.i + Inner.j;
      assertEquals(10, i);
      i = Super.i + Super.j;
      assertEquals(12, i);
      i = other.i + other.j + other.x + other.y;
      assertEquals(21, i);
      i = Inner.this.i + Inner.this.j + Inner.this.x + Inner.this.y;
      assertEquals(30, i);
      i = CoverageTest.this.i + CoverageTest.this.j + CoverageTest.this.x
          + CoverageTest.this.y;
      assertEquals(15, i);
      i = super.i + super.j + super.x + super.y;
      assertEquals(25, i);
      i = Inner.super.i + Inner.super.j + Inner.super.x + Inner.super.y;
      assertEquals(35, i);
      i = CoverageTest.super.i + CoverageTest.super.j + CoverageTest.super.x
          + CoverageTest.super.y;
      assertEquals(10, i);
      return other;
    }

    private void testReturnStatement() {
      // ReturnStatement
      assertEquals("foo", doReturnFoo());
      if (true) {
        return;
      }
      fail();
    }

    private void testSynchronizedStatement() {
      // SynchronizedStatement
      synchronized (inner) {
        inner.i = i;
      }
    }

    private void testTryCatchFinallyThrowStatement() {
      // ThrowStatement, TryStatement
      try {
        i = 3;
        if (true) {
          throw new Exception();
        }
        fail();
      } catch (Exception e) {
      } finally {
        i = 7;
      }
      assertEquals(7, i);

      try {
        try {
          i = 3;
        } catch (Throwable t) {
          fail();
        }
      } catch (Throwable t) {
        fail();
      } finally {
        i = 7;
      }
      assertEquals(7, i);
    }

    private void testUnaryExpression() {
      // UnaryExpression
      i = 4;
      assertEquals(-4, -i);
      assertEquals(-5, ~i);
      z = true;
      assertFalse(!z);
    }

    private void testWhileStatement() {
      // WhileStatement
      z = false;
      while (z) {
        fail();
      }
    }
  }

  /**
   * TODO: document me.
   */
  public static class Super {
    public static int i = 2;
    public static final int j = 2;

    // Initializer
    static {
      Super.i = 1;
    }

    // Initializer
    static {
      Super.i = 3;
    }

    protected static void sfoo() {
    }

    public int x = 2;
    public final int y = 4;

    // Initializer
    {
      x = 1;
    }

    // Initializer
    {
      x = 3;
    }

    public Super() {
    }

    public Super(int i) {
      x = i;
    }

    public void foo() {
    }

    @Override
    public String toString() {
      return String.valueOf(x);
    }
  }

  private static class InnerSub extends Inner {
    private class InnerSubSub extends InnerSub {
      {
        asdfasdfasdf = InnerSub.this.asdfasdfasdf;
        InnerSub.this.asdfasdfasdf = asdfasdfasdf;
        asdfasdfasdf = super.asdfasdfasdf;
        super.asdfasdfasdf = asdfasdfasdf;
      }

      void fda() {
        asdfasdfasdf = InnerSub.this.asdfasdfasdf;
        InnerSub.this.asdfasdfasdf = asdfasdfasdf;
        asdfasdfasdf = super.asdfasdfasdf;
        super.asdfasdfasdf = asdfasdfasdf;
      }
    }

    private int asdfasdfasdf = 3;

    InnerSub() {
      new CoverageTest().super();
    }
  }

  private static class SecondMain {
    private class FunkyInner extends Inner {
      FunkyInner() {
        new CoverageTest().super();
      }
    }
  }

  public static double d;

  public static float f;

  public static int i = 1 + 2 + 3;

  public static int[] ia;

  public static int[][] iaa;

  public static int[][][] iaaa;

  public static final int j = 2;

  public static long l;

  public static Object o;

  public static String s = "foo";

  public static String[] sa = new String[]{"foo", "bar", "bar"};

  public static CoverageTest singleton;

  public static boolean z;

  public static boolean betterNotEval() {
    fail();
    return false;
  }

  @Override
  public void gwtSetUp() throws Exception {
    super.gwtSetUp();
    x = 3;
    d = 0;
    f = 0;
    i = 1 + 2 + 3;
    ia = null;
    iaa = null;
    iaaa = null;
    l = 0;
    o = null;
    s = "foo";
    sa = new String[]{"foo", "bar", "bar"};
    z = false;
  }
  
  protected static void sfoo() {
  }

  private static String doReturnFoo() {
    if (true) {
      return "foo";
    }
    fail();
    return "bar";
  }

  public final Inner inner = new Inner();

  public CoverageTest next;

  public int x = 3;

  public final int y = 4;

  public CoverageTest() {
    if (singleton == null) {
      singleton = this;
    }
    next = this;
  }

  @Override
  public void foo() {
  }

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

  public CoverageTest getNext() {
    return next;
  }

  public void testAllocationExpression() {
    inner.testAllocationExpression();
  }

  public void testAndAndExpression() {
    inner.testAndAndExpression();
  }

  public void testArrayAllocationExpression() {
    inner.testArrayAllocationExpression();
  }

  public void testArrayInitializer() {
    inner.testArrayInitializer();
  }

  public void testArrayReference() {
    inner.testArrayReference();
  }

  public void testAssertStatement() {
    inner.testAssertStatement();
  }

  public void testAssignment() {
    inner.testAssignment();
  }

  public void testBinaryExpression() {
    inner.testBinaryExpression();
  }

  public void testBreakContinueLabelStatement() {
    inner.testBreakContinueLabelStatement();
  }

  public void testCaseSwitchStatement() {
    inner.testCaseSwitchStatement();
  }

  public void testCastExpression() {
    inner.testCastExpression();
  }

  public void testCharLiteral() {
    inner.testCharLiteral();
  }

  public void testClassLiteralAccess() {
    inner.testClassLiteralAccess();
  }

  public void testCompoundAssignment() {
    inner.testCompoundAssignment();
  }

  public void testConditionalExpression() {
    inner.testConditionalExpression();
  }

  public void testDoStatement() {
    inner.testDoStatement();
  }

  public void testEmptyStatement() {
    inner.testEmptyStatement();
  }

  public void testEqualExpression() {
    inner.testEqualExpression();
  }

  public void testForeachStatement() {
    inner.testForeachStatement();
  }

  public void testForStatement() {
    inner.testForStatement();
  }

  public void testIfStatement() {
    inner.testIfStatement();
  }

  public void testInstanceOfExpression() {
    inner.testInstanceOfExpression();
  }

  public void testLiterals() {
    inner.testLiterals();
  }

  public void testOrOrExpression() {
    inner.testOrOrExpression();
  }

  public void testPostfixExpression() {
    inner.testPostfixExpression();
  }

  public void testPrefixExpression() {
    inner.testPrefixExpression();
  }

  public void testQualifiedAllocationExpression() {
    inner.testQualifiedAllocationExpression();
  }

  public void testQualifiedNameReference() {
    inner.testQualifiedNameReference();
  }

  public void testReferenceCalls() {
    inner.testReferenceCalls();
  }

  public void testReferences() {
    inner.testReferences();
  }

  public void testReturnStatement() {
    inner.testReturnStatement();
  }

  public void testSynchronizedStatement() {
    inner.testSynchronizedStatement();
  }

  public void testTryCatchFinallyThrowStatement() {
    inner.testTryCatchFinallyThrowStatement();
  }

  public void testUnaryExpression() {
    inner.testUnaryExpression();
  }

  public void testWhileStatement() {
    inner.testWhileStatement();
  }

}

abstract class CoverageBase extends GWTTestCase {

  public static int i = 1;
  public static final int j = 2;

  protected static void sfoo() {
  }

  public int x = 3;
  public final int y = 4;

  public void foo() {
  }

}
