/*
 * 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.impl;

import com.google.gwt.core.client.Callback;
import com.google.gwt.core.client.ScriptInjector;
import com.google.gwt.core.client.impl.AsyncFragmentLoader.HttpDownloadFailure;

/**
 * A download strategy that uses a JSONP style script tag mechanism. and is
 * therefore cross site compatible. Note that if this strategy is used, the
 * deferred fragments must be wrapped in a callback called runAsyncCallbackX()
 * where X is the fragment number.
 *
 * This is the default strategy for the CrossSiteIframeLinker.
 */

public class ScriptTagLoadingStrategy extends LoadingStrategyBase {

  /**
   * Uses a JSONP style script tag mechanism to download the code.
   */
  // Visible for testing.
  public static class ScriptTagDownloadStrategy implements DownloadStrategy {
    @Override
    public void tryDownload(final RequestData request) {
      setAsyncCallback(request.getFragment(), request);

      ScriptInjector.fromUrl(request.getUrl()).setRemoveTag(true).setCallback(
        new Callback<Void, Exception>() {
          @Override
          public void onFailure(Exception reason) {
            cleanup(request);
          }

          @Override
          public void onSuccess(Void result) {
            cleanup(request);
          }
      }).inject();
    }
  }

  private static void asyncCallback(RequestData request, String code) {
    boolean firstTimeCalled = clearAsyncCallback(request.getFragment());
    if (firstTimeCalled) {
      request.tryInstall(code);
    }
  }

  private static void cleanup(RequestData request) {
    boolean neverCalled = clearAsyncCallback(request.getFragment());
    if (neverCalled) {
      request.onLoadError(new HttpDownloadFailure(request.getUrl(), 404,
        "Script Tag Failure - no status available"), true);
    }
  }

  /**
   * Returns true if the callback existed.
   */
  private static native boolean clearAsyncCallback(int fragment) /*-{
    if (!__gwtModuleFunction['runAsyncCallback' + fragment]) {
      return false;
    }
    delete __gwtModuleFunction['runAsyncCallback' + fragment];
    return true;
  }-*/;

  private static native void setAsyncCallback(int fragment, RequestData request) /*-{
    __gwtModuleFunction['runAsyncCallback' + fragment] = $entry(function(code, instance) {
      @com.google.gwt.core.client.impl.ScriptTagLoadingStrategy::asyncCallback(Lcom/google/gwt/core/client/impl/LoadingStrategyBase$RequestData;Ljava/lang/String;)(
        request, code);
    });
  }-*/;

  public ScriptTagLoadingStrategy() {
    super(new ScriptTagDownloadStrategy());
  }
}
