/*
 * Copyright 2009 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.jsonp.client;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Node;
import com.google.gwt.dom.client.ScriptElement;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;

/**
 * A JSONP request that is waiting for a response. The request can be canceled.
 *
 * @param <T> the type of the response object.
 */
public class JsonpRequest<T> {

  /**
   * A global JS variable that holds the next index to use.
   */
  private static final String CALLBACKS_COUNTER_NAME = "__gwt_jsonp_counter__";

  /**
   * A global JS object that contains callbacks of pending requests.
   */
  private static final String CALLBACKS_NAME = "__gwt_jsonp__";
  private static final JavaScriptObject CALLBACKS = getOrCreateCallbacksObject();

  /**
   * Prefix appended to all id's that are determined by the callbacks counter.
   */
  private static final String INCREMENTAL_ID_PREFIX = "P";

  /**
   * Prefix appended to all id's that are passed in by the user. The "P" 
   * suffix must stay in sync with ExternalTextResourceGenerator.java
   */
  private static final String PREDETERMINED_ID_PREFIX = "P";

  /**
   * Returns the next ID to use, incrementing the global counter.
   */
  private static native int getAndIncrementCallbackCounter() /*-{
    var name = @com.google.gwt.jsonp.client.JsonpRequest::CALLBACKS_NAME;
    var ctr = @com.google.gwt.jsonp.client.JsonpRequest::CALLBACKS_COUNTER_NAME;
    return $wnd[name][ctr]++;
  }-*/;

  private static Node getHeadElement() {
    return Document.get().getElementsByTagName("head").getItem(0);
  }

  /**
   * Returns a global object to store callbacks of pending requests, creating
   * it if it doesn't exist.
   */
  private static native JavaScriptObject getOrCreateCallbacksObject() /*-{
    var name = @com.google.gwt.jsonp.client.JsonpRequest::CALLBACKS_NAME;
    if (!$wnd[name]) {
      $wnd[name] = new Object();
      $wnd[name]
          [@com.google.gwt.jsonp.client.JsonpRequest::CALLBACKS_COUNTER_NAME]
          = 0;
    }
    return $wnd[name];
  }-*/;

  private static String getPredeterminedId(String suffix) {
    return PREDETERMINED_ID_PREFIX + suffix;
  }

  private static String nextCallbackId() {
    return INCREMENTAL_ID_PREFIX + getAndIncrementCallbackCounter();
  }

  private final String callbackId;

  private final int timeout;

  private final AsyncCallback<T> callback;

  /**
   * Whether the result is expected to be an integer or not.
   */
  private final boolean expectInteger;

  private final String callbackParam;

  private final String failureCallbackParam;

  private final boolean canHaveMultipleRequestsForSameId;

  /**
   * Timer which keeps track of timeouts.
   */
  private Timer timer;

  /**
   * Create a new JSONP request.
   *
   * @param callback The callback instance to notify when the response comes
   *          back
   * @param timeout Time in ms after which a {@link TimeoutException} will be
   *          thrown
   * @param expectInteger Should be true if T is {@link Integer}, false
   *          otherwise
   * @param callbackParam Name of the url param of the callback function name
   * @param failureCallbackParam Name of the url param containing the the
   *          failure callback function name, or null for no failure callback
   */
  JsonpRequest(AsyncCallback<T> callback, int timeout, boolean expectInteger,
      String callbackParam, String failureCallbackParam) {
    callbackId = nextCallbackId();
    this.callback = callback;
    this.timeout = timeout;
    this.expectInteger = expectInteger;
    this.callbackParam = callbackParam;
    this.failureCallbackParam = failureCallbackParam;
    this.canHaveMultipleRequestsForSameId = false;
  }

  /**
   * Create a new JSONP request with a hardcoded id. This could be used to
   * manually control which resources are considered duplicates (by giving them
   * identical ids). Could also be used if the callback name needs to be
   * completely user controlled (since the id is part of the callback name).
   *
   * @param callback The callback instance to notify when the response comes
   *          back
   * @param timeout Time in ms after which a {@link TimeoutException} will be
   *          thrown
   * @param expectInteger Should be true if T is {@link Integer}, false
   *          otherwise
   * @param callbackParam Name of the url param of the callback function name
   * @param failureCallbackParam Name of the url param containing the the
   *          failure callback function name, or null for no failure callback
   * @param id unique id for the resource that is being fetched
   */
  JsonpRequest(AsyncCallback<T> callback, int timeout, boolean expectInteger,
      String callbackParam, String failureCallbackParam, String id) {
    callbackId = getPredeterminedId(id);
    this.callback = callback;
    this.timeout = timeout;
    this.expectInteger = expectInteger;
    this.callbackParam = callbackParam;
    this.failureCallbackParam = failureCallbackParam;
    this.canHaveMultipleRequestsForSameId = true;
  }

  /**
   * Cancels a pending request.  Note that if you are using preset ID's, this
   * will not work, since there is no way of knowing if there are other
   * requests pending (or have already returned) for the same data.
   */
  public void cancel() {
    timer.cancel();
    unload();
  }

  public AsyncCallback<T> getCallback() {
    return callback;
  }

  public int getTimeout() {
    return timeout;
  }

  @Override
  public String toString() {
    return "JsonpRequest(id=" + callbackId + ")";
  }

  // @VisibleForTesting
  String getCallbackId() {
    return callbackId;
  }

  /**
   * Sends a request using the JSONP mechanism.
   *
   * @param baseUri To be sent to the server.
   */
  void send(final String baseUri) {
    registerCallbacks(CALLBACKS, canHaveMultipleRequestsForSameId);
    StringBuffer uri = new StringBuffer(baseUri);
    uri.append(baseUri.contains("?") ? "&" : "?");
    String prefix = CALLBACKS_NAME + "." + callbackId;

    uri.append(callbackParam).append("=").append(prefix).append(
        ".onSuccess");
    if (failureCallbackParam != null) {
      uri.append("&");
      uri.append(failureCallbackParam).append("=").append(prefix).append(
          ".onFailure");
    }
    ScriptElement script = Document.get().createScriptElement();
    script.setType("text/javascript");
    script.setId(callbackId);
    script.setSrc(uri.toString());
    timer = new Timer() {
      @Override
      public void run() {
        onFailure(new TimeoutException("Timeout while calling " + baseUri));
      }
    };
    timer.schedule(timeout);
    getHeadElement().appendChild(script);
  }
  
  private void onFailure(String message) {
    onFailure(new Exception(message));
  }

  private void onFailure(Throwable ex) {
    timer.cancel();
    try {
      if (callback != null) {
        callback.onFailure(ex);
      }
    } finally {
      unload();
    }
  }

  private void onSuccess(T data) {
    timer.cancel();
    try {
      if (callback != null) {
        callback.onSuccess(data);
      }
    } finally {
      unload();
    }
  }

  /**
   * Registers the callback methods that will be called when the JSONP response
   * comes back. 2 callbacks are created, one to return the value, and one to
   * notify a failure.
   *
   * @param callbacks the global JS object which stores callbacks
   */
  private native void registerCallbacks(JavaScriptObject callbacks, boolean canHaveMultipleRequestsForId) /*-{
    var self = this;
    var callback = new Object();
    callback.onSuccess = $entry(function(data) {
      // Box primitive types
      if (typeof data == 'boolean') {
        data = @java.lang.Boolean::new(Z)(data);
      } else if (typeof data == 'number') {
        if (self.@com.google.gwt.jsonp.client.JsonpRequest::expectInteger) {
          data = @java.lang.Integer::new(I)(data);
        } else {
          data = @java.lang.Double::new(D)(data);
        }
      }
      self.@com.google.gwt.jsonp.client.JsonpRequest::onSuccess(Ljava/lang/Object;)(data);
    });
    if (this.@com.google.gwt.jsonp.client.JsonpRequest::failureCallbackParam) {
      callback.onFailure = $entry(function(message) {
        self.@com.google.gwt.jsonp.client.JsonpRequest::onFailure(Ljava/lang/String;)(message);
      });
    }
    
    if (canHaveMultipleRequestsForId) {
      // In this case, we keep a wrapper, with a list of callbacks.  Since the
      // response for the request is the same each time, we call all of the
      // callbacks as soon as any response comes back.
      var callbackWrapper =
        callbacks[this.@com.google.gwt.jsonp.client.JsonpRequest::callbackId];
      if (!callbackWrapper) {
        callbackWrapper = new Object();
        callbackWrapper.callbackList = new Array();

        callbackWrapper.onSuccess = function(data) {
          while (callbackWrapper.callbackList.length > 0) {
            callbackWrapper.callbackList.shift().onSuccess(data);
          }
        } 
        callbackWrapper.onFailure = function(data) {
          while (callbackWrapper.callbackList.length > 0) {
            callbackWrapper.callbackList.shift().onFailure(data);
          }
        } 
        callbacks[this.@com.google.gwt.jsonp.client.JsonpRequest::callbackId] =
          callbackWrapper;
      }
      callbackWrapper.callbackList.push(callback);
    } else {
      // In this simple case, just associate the callback directly with the
      // particular id in the callbacks object
      callbacks[this.@com.google.gwt.jsonp.client.JsonpRequest::callbackId] = callback;
    }
  }-*/;

  /**
   * Cleans everything once the response has been received: deletes the script
   * tag and unregisters the callback.
   */
  private void unload() {
    /*
     * Some browsers (IE7) require the script tag to be deleted outside the
     * scope of the script itself. Therefore, we need to defer the delete
     * statement after the callback execution.
     */
    DeferredCommand.addCommand(new Command() {
      public void execute() {
        if (!canHaveMultipleRequestsForSameId) {
          // If there can me multiple requests for a particular ID, then we
          // don't want to unregister the callback since there may be pending
          // requests that have not yet come back and we don't want them to
          // have an undefined callback function.
          unregisterCallbacks(CALLBACKS);
        }
        Node script = Document.get().getElementById(callbackId);
        if (script != null) {
          // The script may have already been deleted
          getHeadElement().removeChild(script);
        }
      }
    });
  }

  private native void unregisterCallbacks(JavaScriptObject callbacks) /*-{
    delete callbacks[this.@com.google.gwt.jsonp.client.JsonpRequest::callbackId];
  }-*/;
}
