/*
 * Copyright 2015 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.testing.TestUtils;

import jsinterop.annotations.JsMethod;
import jsinterop.annotations.JsPackage;
import jsinterop.annotations.JsType;

/**
 * Unit tests for JsException behavior.
 */
public class JsExceptionTest extends ThrowableTestBase {

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

  // Override removed here to make the test compile in J2CL.
  // @Override
  public void runTest() throws Throwable {
    // Do not run  these tests in JVM.
    if (TestUtils.isJvm()) {
      return;
    }
  }

  public void testCatchJava() {
    Object obj = new Object();
    Throwable e = createJsException(obj);
    assertJsException(obj, catchJava(createThrower(e)));
  }

  public void testCatchNative() {
    Object obj = new Object();
    Throwable e = createJsException(obj);
    assertSame(obj, catchNative(createThrower(e)));
  }

  public void testCatchNativePropagatedFromFinally() {
    Object obj = new Object();
    Throwable e = createJsException(obj);
    assertSame(obj, catchNative(wrapWithFinally(createThrower(e))));
    assertTrue(keepFinallyAlive);
  }

  private static boolean keepFinallyAlive = false;

  private static Thrower wrapWithFinally(final Thrower thrower) {
    return new Thrower() {
      @Override public void throwException() throws Throwable {
        try {
          thrower.throwException();
        } finally {
          keepFinallyAlive = true;
        }
      }
    };
  }

  public void testJavaNativeJavaSandwichCatch() {
    Object obj = new Object();
    Throwable e = createJsException(obj);
    assertJsException(obj, javaNativeJavaSandwich(e));
  }

  public void testCatchThrowNative() {
    Object e;

    e = "testing";
    assertJsException(e, catchJava(createNativeThrower(e)));

    e = null;
    assertJsException(e, catchJava(createNativeThrower(e)));

    e = new Object();
    assertJsException(e, catchJava(createNativeThrower(e)));
  }

  // jsni throw -> java catch -> java throw -> jsni catch
  public void testNativeJavaNativeSandwichCatch() {
    Object e;

    e = "testing";
    assertEquals(e, nativeJavaNativeSandwich(e));
    // Devmode will not preserve the same String instance
    assertEquals(e, nativeJavaNativeSandwich(e));

    e = null;
    assertSame(e, nativeJavaNativeSandwich(e));

    e = new Object();
    assertSame(e, nativeJavaNativeSandwich(e));
  }

  private Object nativeJavaNativeSandwich(Object e) {
    return catchNative(createThrower(catchJava(createNativeThrower(e))));
  }

  public void testTypeError() {
    try {
      throwTypeError();
      fail();
    } catch (RuntimeException e) {
      assertTypeError(e);
      e = (RuntimeException) javaNativeJavaSandwich(e);
      assertTypeError(e);
    }
  }

  private static void throwTypeError() {
    Object nullObject = null;
    nullObject.toString();
  }

  @JsType(isNative = true, namespace = "<window>")
  private static class TypeError { }

  protected static void assertTypeError(RuntimeException e) {
    assertTrue(getBackingJsObject(e) instanceof TypeError);
    assertTrue(e.toString().contains("TypeError"));
  }

  public void testSvgError() {
    try {
      throwSvgError();
      fail();
    } catch (RuntimeException e) {
      e = (RuntimeException) javaNativeJavaSandwich(e);
    }
  }

  private static void throwSvgError() {
    // In old Firefox, this throws an object (not Error):
    createElementNS("http://www.w3.org/2000/svg", "text").getBBox();

    // For other browsers, make sure an exception is thrown to keep the test simple
    throw new RuntimeException("NS_ERROR_FAILURE");
  }

  @JsMethod(name = "document.createElementNS", namespace = JsPackage.GLOBAL)
  private static native SVGElement createElementNS(String arg1, String arg2);

  @JsType(isNative = true, namespace = JsPackage.GLOBAL)
  private interface SVGElement {
    void getBBox();
  }

  private static void assertJsException(Object expected, Throwable exception) {
    assertTrue(exception instanceof RuntimeException);
    assertEquals(expected, getBackingJsObject(exception));
  }
}
