/*
 * Copyright 2014 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.optimized;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.junit.DoNotRunWith;
import com.google.gwt.junit.Platform;

import java.util.Random;

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

/**
 * Tests cast checks are optimized out when cast checking is disabled.
 */
@DoNotRunWith(Platform.Devel)
public class CastOptimizationTest extends OptimizationTestBase {

  private static class TestObject { }

  @JsType(isNative = true)
  private interface JsTypeTestInterface { }

  private interface DualJsoTestInterface { }

  private static class JsoTestObject extends JavaScriptObject implements DualJsoTestInterface {
    protected JsoTestObject() { }
  }

  @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
  static class NativeObject {
  }

  @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Function")
  static class NativeFunction {
  }

  @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Array")
  static class NativeArray {
  }

  @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Number")
  static class NativeNumber {
  }

  @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "String")
  static class NativeString {
  }

  private static Object field;
  private static double doubleField = new Random().nextDouble();

  private static int randomNumber = new Random().nextInt(42);

  @Override
  protected void gwtSetUp() throws Exception {
    field = createField();
  }

  private static Object createField() {
    // Makes sure that field type is not upgradable even the compiler becomes really smart and also
    // no types are pruned otherwise casts can be statically evaluated.
    switch (randomNumber) {
      case 0:
        return new TestObject();
      case 1:
        return JavaScriptObject.createObject();
      case 2:
        return new DualJsoTestInterface() { };
      case 3:
        return "Some string";
      default:
        return null;
    }
  }

  public static TestObject castOp() {
    return ((TestObject) field);
  }

  public static JavaScriptObject castOpJso() {
    return ((JavaScriptObject) field);
  }

  public static DualJsoTestInterface castOpDualJso() {
    return ((DualJsoTestInterface) field);
  }

  public static JavaScriptObject castOpJsType() {
    return ((JavaScriptObject) field);
  }

  public static String castOpString() {
    return ((String) field);
  }

  public static NativeFunction castNativeFunction() {
    return ((NativeFunction) field);
  }

  public static NativeObject castNativeObject() {
    return ((NativeObject) field);
  }

  public static NativeArray castNativeArray() {
    return ((NativeArray) field);
  }

  public static NativeNumber castNativeNumber() {
    return ((NativeNumber) field);
  }

  public static void castInt() {
    int num = ((int) doubleField);
  }

  private static native String getGeneratedCastFunctionDefinition() /*-{
    return function() {
      @CastOptimizationTest::castOp()();
      @CastOptimizationTest::castOpJso()();
      @CastOptimizationTest::castOpDualJso()();
      @CastOptimizationTest::castOpJsType()();
      @CastOptimizationTest::castOpString()();
      @CastOptimizationTest::castNativeFunction()();
      @CastOptimizationTest::castNativeNumber()();
      @CastOptimizationTest::castNativeArray()();
      @CastOptimizationTest::castNativeObject()();
      @CastOptimizationTest::castInt()();
    }.toString();
  }-*/;

  public void testCastsAreRemoved() throws Exception {
    String functionDef = getGeneratedCastFunctionDefinition();
    assertFunctionMatches(functionDef, "");
  }

  private static native String getGeneratedNullnessPropagationFunctionDefinition() /*-{
    return function() {
      @CastOptimizationTest::castNonNullnessCheck()();
    }.toString();
  }-*/;

  public static void castNonNullnessCheck() {
    if ((String) (randomNumber == 1 ?  "uniqueCastString" :  new Object()) == null) {
      throw new RuntimeException();
    }
  }

  public void testCastsPropagatesNullness() throws Exception {
    String functionDef = getGeneratedNullnessPropagationFunctionDefinition();
    // Means that the function was inlined but the throw was optimized away.
    assertFunctionMatches(functionDef, "<obf>==1?'uniqueCastString':new<obf>()");
  }
}
