/*
 * Copyright 2008 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.resources.client.impl;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.jsonp.client.JsonpRequestBuilder;
import com.google.gwt.resources.client.ExternalTextResource;
import com.google.gwt.resources.client.ResourceCallback;
import com.google.gwt.resources.client.ResourceException;
import com.google.gwt.resources.client.TextResource;
import com.google.gwt.safehtml.shared.SafeUri;
import com.google.gwt.safehtml.shared.annotations.SuppressIsTrustedResourceUriCastCheck;
import com.google.gwt.user.client.rpc.AsyncCallback;

/**
 * Implements external resource fetching of TextResources.
 */
public class ExternalTextResourcePrototype implements ExternalTextResource {

  /**
   * Maps the HTTP callback onto the ResourceCallback.
   */
  private class ETRCallback implements RequestCallback, AsyncCallback<JavaScriptObject> {
    final ResourceCallback<TextResource> callback;

    public ETRCallback(ResourceCallback<TextResource> callback) {
      this.callback = callback;
    }

    // For RequestCallback
    public void onError(Request request, Throwable exception) {
      onFailure(exception);
    }

    // For AsyncCallback
    public void onFailure(Throwable exception) {
      callback.onError(new ResourceException(
          ExternalTextResourcePrototype.this,
          "Unable to retrieve external resource", exception));
    }

    // For RequestCallback
    public void onResponseReceived(Request request, final Response response) {
      String responseText = response.getText();
      // Call eval() on the object.
      JavaScriptObject jso = evalObject(responseText);
      onSuccess(jso);
     }

    // For AsyncCallback
    public void onSuccess(JavaScriptObject jso) {
      if (jso == null) {
        callback.onError(new ResourceException(
            ExternalTextResourcePrototype.this, "eval() returned null"));
        return;
      }

      // Populate the TextResponse cache array
      final String resourceText = extractString(jso, index);
      cache[index] = new TextResource() {

        public String getName() {
          return name;
        }

        public String getText() {
          return resourceText;
        }

      };

      // Finish by invoking the callback
      callback.onSuccess(cache[index]);
    }
  }

  /**
   * Evaluate the JSON payload. The regular expression to validate the safety of
   * the payload is taken from RFC 4627 (D. Crockford).
   * 
   * @param data the raw JSON-encapsulated string bundle
   * @return the evaluated JSON object, or <code>null</code> if there is an
   *         error.
   */
  private static native JavaScriptObject evalObject(String data) /*-{
    var safe = !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
      data.replace(/"(\\.|[^"\\])*"/g, '')));

    if (!safe) {
      return null;
    }

    return eval('(' + data + ')') || null;
  }-*/;

  /**
   * Extract the specified String from a JavaScriptObject that is array-like.
   * 
   * @param jso the JavaScriptObject returned from {@link #evalObject(String)}
   * @param index the index of the string to extract
   * @return the requested string, or <code>null</code> if it does not exist.
   */
  private static native String extractString(JavaScriptObject jso, int index) /*-{
    return (jso.length > index) && jso[index] || null;
  }-*/;

  /**
   * This is a reference to an array nominally created in the IRB that contains
   * the ExternalTextResource. It is intended to be shared between all instances
   * of the ETR that have a common parent IRB.
   */
  private final TextResource[] cache;
  private final int index;
  private final String md5Hash;
  private final String name;
  private final SafeUri url;

  public ExternalTextResourcePrototype(String name, SafeUri url,
      TextResource[] cache, int index) {
    this.name = name;
    this.url = url;
    this.cache = cache;
    this.index = index;
    this.md5Hash = null;
  }

  public ExternalTextResourcePrototype(String name, SafeUri url,
      TextResource[] cache, int index, String md5Hash) {
    this.name = name;
    this.url = url;
    this.cache = cache;
    this.index = index;
    this.md5Hash = md5Hash;
  }

  public String getName() {
    return name;
  }

  /**
   * Possibly fire off an HTTPRequest for the text resource.
   */
  @SuppressIsTrustedResourceUriCastCheck
  public void getText(ResourceCallback<TextResource> callback) throws ResourceException {

    // If we've already parsed the JSON bundle, short-circuit.
    if (cache[index] != null) {
      callback.onSuccess(cache[index]);
      return;
    }

    if (md5Hash != null) {
      // If we have an md5Hash, we should be using JSONP
      JsonpRequestBuilder rb = new JsonpRequestBuilder();
      rb.setPredeterminedId(md5Hash);
      rb.requestObject(url.asString(), new ETRCallback(callback));
    } else {
      RequestBuilder rb = new RequestBuilder(RequestBuilder.GET, url.asString());
      try {
        rb.sendRequest("", new ETRCallback(callback));
      } catch (RequestException e) {
        throw new ResourceException(this, "Unable to initiate request for external resource", e);
      }
    }
  }
}
