/*
 * 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.getClass();
  }

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

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

  public void testFrozenObject() {
    try {
      Object e = new TypeError();
      freeze(e);
      throwNative(e);
      fail();
    } catch (RuntimeException e) {
      e = (RuntimeException) javaNativeJavaSandwich(e);
    }
  }

  @JsMethod(name = "Object.freeze", namespace = JsPackage.GLOBAL)
  private static native void freeze(Object o);

  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));
  }
}
