/*
 * Copyright 2011 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.core.client;

import com.google.gwt.core.client.Scheduler.RepeatingCommand;
import com.google.gwt.core.client.ScriptInjector.FromString;
import com.google.gwt.junit.client.GWTTestCase;

/**
 * Tests for {@link ScriptInjector}
 */
public class ScriptInjectorTest extends GWTTestCase {
  private static boolean browserChecked = false;
  private static final int CHECK_DELAY = 100;

  private static boolean isIE = false;
  private static final int TEST_DELAY = 10000;

  /**
   * Check if the browser is IE6,7,8,9.
   * 
   * @return <code>true</code> if the browser is IE6, IE7, IE8, IE9
   *         <code>false</code> any other browser
   */
  static boolean isIE() {
    if (!browserChecked) {
      isIE = isIEImpl();
      browserChecked = true;
    }
    return isIE;
  }

  private static native boolean isIEImpl() /*-{
    var ua = navigator.userAgent.toLowerCase();
    if (ua.indexOf("msie") != -1) {
      return true;
    }
    return false;
  }-*/;

  private native boolean isSafari3OrBefore() /*-{
    return @com.google.gwt.dom.client.DOMImplWebkit::isWebkit525OrBefore()();
  }-*/;
  
  @Override
  public String getModuleName() {
    return "com.google.gwt.core.Core";
  }

  /**
   * Install a script in the same window as GWT.
   */
  public void testInjectDirectThisWindow() {
    delayTestFinish(TEST_DELAY);
    String scriptBody = "__ti1_var__ = 1;";
    assertFalse(nativeTest1Worked());
    new FromString(scriptBody).inject();
    boolean worked = nativeTest1Worked();
    JavaScriptObject scriptElement = findScriptTextInThisWindow(scriptBody);
    if (!isIE()) {
      cleanupThisWindow("__ti1_var__", scriptElement);
      assertFalse("cleanup failed", nativeTest1Worked());
    }
    assertTrue("__ti1_var not set in this window", worked);
    assertNull("script element 1 not removed by injection", scriptElement);
    finishTest();
  }

  /**
   * Install a script in the top window.
   */
  public void testInjectDirectTopWindow() {
    String scriptBody = "__ti2_var__ = 2;";
    assertFalse(nativeTest2Worked());
    ScriptInjector.fromString(scriptBody).setWindow(ScriptInjector.TOP_WINDOW).inject();
    boolean worked = nativeTest2Worked();
    JavaScriptObject scriptElement = findScriptTextInTopWindow(scriptBody);
    if (!isIE()) {
      cleanupTopWindow("__ti2_var__", scriptElement);
      assertTrue("__ti2_var not set in top window", worked);
    }
    assertNull("script element 2 not removed by injection", scriptElement);
  }

  /**
   * Install a script in the same window as GWT, turn off the tag removal.
   */
  public void testInjectDirectWithoutRemoveTag() {
    assertFalse(nativeTest3Worked());
    String scriptBody = "__ti3_var__ = 3;";
    new FromString(scriptBody).setRemoveTag(false).inject();
    boolean worked = nativeTest3Worked();
    JavaScriptObject scriptElement = findScriptTextInThisWindow(scriptBody);
    if (!isIE()) {
      cleanupThisWindow("__ti3_var__", scriptElement);
      assertFalse("cleanup failed", nativeTest3Worked());
    }
    assertTrue(worked);
    assertNotNull("script element 3 should have been left in DOM", scriptElement);
  }

  /**
   * Inject an absolute URL on this window.
   */
  public void testInjectUrlAbsolute() {
    delayTestFinish(TEST_DELAY);
    final String scriptUrl = "http://www.google.com/jsapi?key=GWTUNITEST";
    assertFalse(nativeInjectUrlAbsoluteWorked());
    ScriptInjector.fromUrl(scriptUrl).setCallback(new Callback<Void, Exception>() {

      @Override
      public void onFailure(Exception reason) {
        assertNotNull(reason);
        fail("Injection failed: " + reason.toString());
      }

      @Override
      public void onSuccess(Void result) {
        assertTrue(nativeInjectUrlAbsoluteWorked());
        finishTest();
      }

    }).inject();
  }

  /**
   * Inject an absolute URL on the top level window.
   */
  public void testInjectUrlAbsoluteTop() {
    delayTestFinish(TEST_DELAY);
    final String scriptUrl = "http://www.google.com/jsapi?key=GWTUNITEST_ABSOLUTE";
    assertFalse(nativeAbsoluteTopUrlIsLoaded());
    ScriptInjector.fromUrl(scriptUrl).setWindow(ScriptInjector.TOP_WINDOW).setCallback(
        new Callback<Void, Exception>() {

          @Override
          public void onFailure(Exception reason) {
            assertNotNull(reason);
            fail("Injection failed: " + reason.toString());
          }

          @Override
          public void onSuccess(Void result) {
            assertTrue(nativeAbsoluteTopUrlIsLoaded());
            finishTest();
          }
        }).inject();
  }

  /**
   * This script injection should fail and fire the onFailure callback.
   * 
   * Note, the onerror mechanism used to trigger the failure event is a modern browser
   * feature.
   * 
   * On IE, the script.onerror tag has been documented, but busted for <a
   * href=
   * "http://stackoverflow.com/questions/2027849/how-to-trigger-script-onerror-in-internet-explorer/2032014#2032014"
   * >aeons</a>.
   * 
   */
  public void testInjectUrlFail() {
    if (isIE() || isSafari3OrBefore()) {
      return;
    }
    
    delayTestFinish(TEST_DELAY);
    final String scriptUrl = "uNkNoWn_sCrIpT_404.js";
    JavaScriptObject injectedElement =
        ScriptInjector.fromUrl(scriptUrl).setCallback(new Callback<Void, Exception>() {

          @Override
          public void onFailure(Exception reason) {
            assertNotNull(reason);
            finishTest();
          }

          @Override
          public void onSuccess(Void result) {
            fail("Injection unexpectedly succeeded.");
          }
        }).inject();
    assertNotNull(injectedElement);
  }

  /**
   * Install a script in the same window as GWT by URL
   */
  public void testInjectUrlThisWindow() {
    this.delayTestFinish(TEST_DELAY);
    final String scriptUrl = "script_injector_test4.js";
    assertFalse(nativeTest4Worked());
    final JavaScriptObject injectedElement = ScriptInjector.fromUrl(scriptUrl).inject();

    // We'll check using a callback in another test. This test will poll to see
    // that the script had an effect.
    Scheduler.get().scheduleFixedDelay(new RepeatingCommand() {
      int numLoops = 0;

      @Override
      public boolean execute() {
        numLoops++;
        boolean worked = nativeTest4Worked();
        if (!worked && (numLoops * CHECK_DELAY < TEST_DELAY)) {
          return true;
        }
        JavaScriptObject scriptElement = findScriptUrlInThisWindow(scriptUrl);
        if (!isIE()) {
          cleanupThisWindow("__ti4_var__", scriptElement);
          assertFalse("cleanup failed", nativeTest4Worked());
        }
        assertTrue("__ti4_var not set in this window", worked);
        assertNotNull("script element 4 not found", scriptElement);
        assertEquals(injectedElement, scriptElement);
        finishTest();

        // never reached
        return false;
      }
    }, CHECK_DELAY);
    assertNotNull(injectedElement);
  }

  /**
   * Install a script in the same window as GWT by URL
   */
  public void testInjectUrlThisWindowCallback() {
    delayTestFinish(TEST_DELAY);
    final String scriptUrl = "script_injector_test5.js";
    assertFalse(nativeTest5Worked());
    JavaScriptObject injectedElement =
        ScriptInjector.fromUrl(scriptUrl).setCallback(new Callback<Void, Exception>() {
          @Override
          public void onFailure(Exception reason) {
            assertNotNull(reason);
            fail("Injection failed: " + reason.toString());
          }

          @Override
          public void onSuccess(Void result) {
            boolean worked = nativeTest5Worked();
            JavaScriptObject scriptElement = findScriptUrlInThisWindow(scriptUrl);
            if (!isIE()) {
              cleanupThisWindow("__ti5_var__", scriptElement);
              assertFalse("cleanup failed", nativeTest5Worked());
            }
            assertTrue("__ti5_var not set in this window", worked);
            assertNotNull("script element 5 not found", scriptElement);
            finishTest();
          }
        }).inject();
    assertNotNull(injectedElement);
  }

  /**
   * Install a script in the top window by URL
   */
  public void testInjectUrlTopWindow() {
    final String scriptUrl = "script_injector_test6.js";
    assertFalse(nativeTest6Worked());
    JavaScriptObject injectedElement =
        ScriptInjector.fromUrl(scriptUrl).setWindow(ScriptInjector.TOP_WINDOW).inject();
    // We'll check using a callback in another test. This test will poll to see
    // that the script had an effect.
    Scheduler.get().scheduleFixedDelay(new RepeatingCommand() {
      int numLoops = 0;

      @Override
      public boolean execute() {
        numLoops++;

        boolean worked = nativeTest6Worked();
        if (!worked && (numLoops * CHECK_DELAY < TEST_DELAY)) {
          return true;
        }
        JavaScriptObject scriptElement = findScriptUrlInTopWindow(scriptUrl);
        if (!isIE()) {
          cleanupTopWindow("__ti6_var__", scriptElement);
          assertFalse("cleanup failed", nativeTest6Worked());
        }
        assertTrue("__ti6_var not set in top window", worked);
        assertNotNull("script element 6 not found", scriptElement);
        finishTest();
        // never reached
        return false;
      }
    }, CHECK_DELAY);
    assertNotNull(injectedElement);
  }

  /**
   * Install a script in the top window by URL
   */
  public void testInjectUrlTopWindowCallback() {
    delayTestFinish(TEST_DELAY);
    final String scriptUrl = "script_injector_test7.js";
    assertFalse(nativeTest7Worked());
    JavaScriptObject injectedElement =
        ScriptInjector.fromUrl(scriptUrl).setWindow(ScriptInjector.TOP_WINDOW).setCallback(
            new Callback<Void, Exception>() {

              @Override
              public void onFailure(Exception reason) {
                assertNotNull(reason);
                fail("Injection failed: " + reason.toString());
              }

              @Override
              public void onSuccess(Void result) {
                boolean worked = nativeTest7Worked();
                JavaScriptObject scriptElement = findScriptUrlInTopWindow(scriptUrl);
                if (!isIE()) {
                  cleanupTopWindow("__ti7_var__", scriptElement);
                  assertFalse("cleanup failed", nativeTest7Worked());
                }
                assertTrue("__ti7_var not set in top window", worked);
                assertNotNull("script element 7 not found", scriptElement);
                finishTest();
              }
            }).inject();
    assertNotNull(injectedElement);
  }

  private void cleanupThisWindow(String property, JavaScriptObject scriptElement) {
    cleanupWindow(nativeThisWindow(), property, scriptElement);
  }

  private void cleanupTopWindow(String property, JavaScriptObject scriptElement) {
    cleanupWindow(nativeTopWindow(), property, scriptElement);
  }

  private native void cleanupWindow(JavaScriptObject wnd, String property,
      JavaScriptObject scriptElement) /*-{
    delete wnd[property];
    if (scriptElement) {
      scriptElement.parentNode.removeChild(scriptElement);
    }
  }-*/;

  private JavaScriptObject findScriptTextInThisWindow(String text) {
    return nativeFindScriptText(nativeThisWindow(), text);
  }

  private JavaScriptObject findScriptTextInTopWindow(String text) {
    return nativeFindScriptText(nativeTopWindow(), text);
  }

  private JavaScriptObject findScriptUrlInThisWindow(String url) {
    return nativeFindScriptUrl(nativeThisWindow(), url);
  }

  private JavaScriptObject findScriptUrlInTopWindow(String url) {
    return nativeFindScriptUrl(nativeTopWindow(), url);
  }

  private native boolean nativeAbsoluteTopUrlIsLoaded() /*-{
    return !!$wnd.google && !!$wnd.google.load;
  }-*/;

  private native JavaScriptObject nativeFindScriptText(JavaScriptObject wnd, String text) /*-{
    var scripts = wnd.document.getElementsByTagName("script");
    for ( var i = 0; i < scripts.length; ++i) {
      if (scripts[i].text.match("^" + text)) {
        return scripts[i];
      }
    }
    return null;
  }-*/;

  /**
   * Won't work for all urls, uses a regular expression match
   */
  private native JavaScriptObject nativeFindScriptUrl(JavaScriptObject wnd, String url) /*-{
    var scripts = wnd.document.getElementsByTagName("script");
    for ( var i = 0; i < scripts.length; ++i) {
      if (scripts[i].src.match(url)) {
        return scripts[i];
      }
    }
    return null;
  }-*/;

  private native boolean nativeInjectUrlAbsoluteWorked() /*-{
    return !!window.google && !!window.google.load;
  }-*/;

  private native boolean nativeTest1Worked() /*-{
    return !!window["__ti1_var__"] && window["__ti1_var__"] == 1;
  }-*/;

  private native boolean nativeTest2Worked() /*-{
    return !!$wnd["__ti2_var__"] && $wnd["__ti2_var__"] == 2;
  }-*/;

  private native boolean nativeTest3Worked() /*-{
    return !!window["__ti3_var__"] && window["__ti3_var__"] == 3;
  }-*/;

  private native boolean nativeTest4Worked() /*-{
    return !!window["__ti4_var__"] && window["__ti4_var__"] == 4;
  }-*/;

  private native boolean nativeTest5Worked() /*-{
    return !!window["__ti5_var__"] && window["__ti5_var__"] == 5;
  }-*/;

  private native boolean nativeTest6Worked() /*-{
    return !!$wnd["__ti6_var__"] && $wnd["__ti6_var__"] == 6;
  }-*/;

  private native boolean nativeTest7Worked() /*-{
    return !!$wnd["__ti7_var__"] && $wnd["__ti7_var__"] == 7;
  }-*/;

  private native JavaScriptObject nativeThisWindow() /*-{
    return window;
  }-*/;

  private native JavaScriptObject nativeTopWindow() /*-{
    return $wnd;
  }-*/;
}
