/*
 * Copyright 2007 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.emultest.java.lang;

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

import java.util.Arrays;

/**
 * Tests java.lang.System.
 */
public class SystemTest extends GWTTestCase {

  private static class Bar extends Foo {
    public Bar() {
    }
  }

  private enum EnumImpl implements Interfaz {
    FOO,
    BAR,
    BAZ
  }

  private static class Foo {
    public Foo() {
    }
  }

  private interface Interfaz {
  }

  private static class InterfazImpl implements Interfaz {

    private final String data;

    /**
     * @param data non-null string
     */
    InterfazImpl(String data) {
      this.data = data;
    }

    @Override
    public boolean equals(Object obj) {
      return (obj instanceof InterfazImpl) && ((InterfazImpl) obj).data.equals(
          data);
    }

    @Override
    public int hashCode() {
      return data.hashCode();
    }

    @Override
    public String toString() {
      return "InterfazImpl[data=" + data + "]";
    }
  }

  @Override
  public String getModuleName() {
    return "com.google.gwt.emultest.EmulSuite";
  }

  public void testArraycopyEnumToInterface() {
    EnumImpl[] src = new EnumImpl[]{ EnumImpl.FOO, null, EnumImpl.BAZ };
    Interfaz[] dest = new Interfaz[5];
    Arrays.fill(dest, null);  // undefined != null, wierd.

    System.arraycopy(src, 0, dest, 1, 3);
    assertEquals(
        Arrays.asList(null, EnumImpl.FOO, null, EnumImpl.BAZ, null),
        Arrays.asList(dest));
  }

  public void testArraycopyEnumToObject() {
    EnumImpl[] src = new EnumImpl[]{ EnumImpl.FOO, null, EnumImpl.BAZ };
    Object[] dest = new Object[5];
    Arrays.fill(dest, null);  // undefined != null, wierd.

    System.arraycopy(src, 0, dest, 1, 3);
    assertEquals(
        Arrays.asList(null, EnumImpl.FOO, null, EnumImpl.BAZ, null),
        Arrays.asList(dest));
  }

  public void testArraycopyFailures() {
    int[] src = new int[4];
    int[] dest = new int[] {1, 1, 1, 1};
    double[] destDouble = new double[4];
    String[] strings = new String[4];
    try {
      System.arraycopy(src, 5, dest, 0, 7);
      fail("Should have thrown IndexOutOfBoundsException: src past end");
    } catch (IndexOutOfBoundsException e) {
    }
    try {
      System.arraycopy(src, 0, dest, 5, 7);
      fail("Should have thrown IndexOutOfBoundsException: dest past end");
    } catch (IndexOutOfBoundsException e) {
    }
    try {
      System.arraycopy(src, -1, dest, 0, 4);
      fail("Should have thrown IndexOutOfBoundsException: src ofs negative");
    } catch (IndexOutOfBoundsException e) {
    }
    try {
      System.arraycopy(src, 0, dest, -1, 4);
      fail("Should have thrown IndexOutOfBoundsException: dest ofs negative");
    } catch (IndexOutOfBoundsException e) {
    }
    try {
      System.arraycopy(src, 0, dest, 0, -1);
      fail("Should have thrown IndexOutOfBoundsException: negative length");
    } catch (IndexOutOfBoundsException e) {
    }
    try {
      System.arraycopy("test", 0, dest, 0, 4);
      fail("Should have thrown ArrayStoreException: src not array");
    } catch (ArrayStoreException e) {
    }
    try {
      System.arraycopy(src, 0, "test", 0, 4);
      fail("Should have thrown ArrayStoreException: dest not array");
    } catch (ArrayStoreException e) {
    }
    try {
      System.arraycopy(src, 0, destDouble, 0, 4);
      fail("Should have thrown ArrayStoreException: different primitive types");
    } catch (ArrayStoreException e) {
    }
    try {
      System.arraycopy(strings, 0, dest, 0, 4);
      fail("Should have thrown ArrayStoreException: reference/primitive mismatch");
    } catch (ArrayStoreException e) {
    }
    try {
      System.arraycopy(src, 0, strings, 0, 4);
      fail("Should have thrown ArrayStoreException: primitive/reference mismatch");
    } catch (ArrayStoreException e) {
    }
  }

  public void testArraycopyInterfaceToObject() {
    Interfaz[] src = new Interfaz[]{
        new InterfazImpl("foo"), null, new InterfazImpl("bar") };
    Object[] dest = new Object[5];
    Arrays.fill(dest, null);  // undefined != null, wierd.

    System.arraycopy(src, 0, dest, 1, 3);
    assertEquals(Arrays.asList(null, new InterfazImpl("foo"), null,
        new InterfazImpl("bar"), null), Arrays.asList(dest));
  }

  public void testArraycopyMultidim() {
    Object[][] objArray = new Object[1][1];
    String[][] strArray = new String[1][1];
    strArray[0][0] = "Test";
    Integer[][] intArray = new Integer[1][1];
    intArray[0][0] = new Integer(1);
    System.arraycopy(strArray, 0, objArray, 0, 1);
    assertEquals("Test", objArray[0][0]);
    try {
      System.arraycopy(strArray, 0, intArray, 0, 1);
      fail("Should have thrown ArrayStoreException: incompatible multidimensional arrays");
    } catch (ArrayStoreException e) {
    }
    try {
      System.arraycopy(new String[] {"T2"}, 0, objArray, 0, 1);
      fail("Should have thrown ArrayStoreException: store string array in multi-dim Object array");
    } catch (ArrayStoreException e) {
    }
  }

  public void testArraycopyNulls() {
    int[] src = new int[4];
    int[] dest = new int[] {1, 1, 1, 1};
    try {
      System.arraycopy(null, 0, dest, 0, 4);
      fail("Should have thrown NullPointerException: src null");
    } catch (NullPointerException e) {
      // verify dest unchanged
      for (int i = 0; i < dest.length; ++i) {
        assertEquals(1, dest[i]);
      }
    }
    try {
      System.arraycopy(src, 0, null, 0, 4);
      fail("Should have thrown NullPointerException: dest null");
    } catch (NullPointerException e) {
    }
  }

  public void testArraycopyObjects() {
    Foo[] fooArray = new Foo[4];
    Bar[] barArray = new Bar[4];
    Object[] src = new Object[] {new Bar(), new Bar(), new Foo(), new Bar()};
    System.arraycopy(src, 0, fooArray, 0, src.length);
    for (int i = 0; i < src.length; ++i) {
      assertEquals(src[i], fooArray[i]);
    }
    try {
      System.arraycopy(src, 0, barArray, 0, 4);
      fail("Should have thrown ArrayStoreException: foo into bar");
    } catch (ArrayStoreException e) {
      // verify we changed only up to the element causing the exception
      assertEquals(src[0], barArray[0]);
      assertEquals(src[1], barArray[1]);
      assertNull(barArray[2]);
      assertNull(barArray[3]);
    }
  }
  
  public void testArraycopyOverlap() {
    int[] intArray = new int[] {0, 1, 2, 3};
    String[] strArray = new String[] {"0", "1", "2", "3"};

    System.arraycopy(intArray, 0, intArray, 1, intArray.length - 1);
    assertEquals(0, intArray[0]);
    for (int i = 1; i < intArray.length; ++i) {
      assertEquals("rev int copy index " + i, i - 1, intArray[i]);
    }
    System.arraycopy(intArray, 1, intArray, 0, intArray.length - 1);
    for (int i = 0; i < intArray.length - 1; ++i) {
      assertEquals("fwd int copy index " + i, i, intArray[i]);
    }
    assertEquals("fwd int copy index " + (intArray.length - 2),
        intArray.length - 2, intArray[intArray.length - 1]);
    System.arraycopy(strArray, 0, strArray, 1, strArray.length - 1);
    assertEquals(0, Integer.valueOf(strArray[0]).intValue());
    for (int i = 1; i < strArray.length; ++i) {
      assertEquals("rev str copy index " + i, i - 1, Integer.valueOf(
          strArray[i]).intValue());
    }
    System.arraycopy(strArray, 1, strArray, 0, strArray.length - 1);
    for (int i = 0; i < strArray.length - 1; ++i) {
      assertEquals("fwd str copy index " + i, i, Integer.valueOf(
          strArray[i]).intValue());
    }
    assertEquals("fwd str copy index " + (strArray.length - 2),
        strArray.length - 2,
        Integer.valueOf(strArray[strArray.length - 1]).intValue());
    /*
     * TODO(jat): how is it supposed to behave with overlapped copies if there
     * is a failure in the middle of the copy? We should figure that out and
     * test for it.
     */
  }

  public void testArraycopyPrimitives() {
    int[] src = new int[] {0, 1, 2, 3, 4, 5, 6, 7};
    int[] dest = new int[8];

    System.arraycopy(src, 0, dest, 0, src.length);
    for (int i = 0; i < src.length; ++i) {
      assertEquals(src[i], dest[i]);
    }
    System.arraycopy(src, 2, dest, 1, 5);
    assertEquals(0, dest[0]);
    for (int i = 1; i < 6; ++i) {
      assertEquals(src[i + 1], dest[i]);
    }
  }
}
