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

import com.google.gwt.core.client.JavaScriptException;
import com.google.gwt.xhr.client.ReadyStateChangeHandler;
import com.google.gwt.xhr.client.XMLHttpRequest;

import java.util.HashMap;
import java.util.Map;

/**
 * Builder for constructing {@link com.google.gwt.http.client.Request} objects.
 * 
 * <h3>Required Module</h3> Modules that use this class should inherit
 * <code>com.google.gwt.http.HTTP</code>.
 * 
 * {@gwt.include
 * com/google/gwt/examples/http/InheritsExample.gwt.xml}
 * 
 */
public class RequestBuilder {
  /**
   * HTTP request method constants.
   */
  public static final class Method {
    private final String name;

    private Method(String name) {
      this.name = name;
    }

    @Override
    public String toString() {
      return name;
    }
  }

  /**
   * Specifies that the HTTP DELETE method should be used.
   */
  public static final Method DELETE = new Method("DELETE");

  /**
   * Specifies that the HTTP GET method should be used.
   */
  public static final Method GET = new Method("GET");

  /**
   * Specifies that the HTTP HEAD method should be used.
   */
  public static final Method HEAD = new Method("HEAD");

  /**
   * Specifies that the HTTP POST method should be used.
   */
  public static final Method POST = new Method("POST");

  /**
   * Specifies that the HTTP PUT method should be used.
   */
  public static final Method PUT = new Method("PUT");

  /**
   * The callback to call when the request completes.
   */
  private RequestCallback callback;

  /**
   * Map of header name to value that will be added to the JavaScript
   * XmlHttpRequest object before sending a request.
   */
  private Map<String, String> headers;

  /**
   * HTTP method to use when opening a JavaScript XmlHttpRequest object.
   */
  private final String httpMethod;

  /**
   * Whether to include credentials for a Cross Origin Request.
   */
  private boolean includeCredentials;

  /**
   * Password to use when opening a JavaScript XmlHttpRequest object.
   */
  private String password;

  /**
   * Request data to use when sending a JavaScript XmlHttpRequest object.
   */
  private String requestData;

  /**
   * Timeout in milliseconds before the request timeouts and fails.
   */
  private int timeoutMillis;

  /**
   * URL to use when opening a JavaScript XmlHttpRequest object.
   */
  private final String url;

  /**
   * User to use when opening a JavaScript XmlHttpRequest object.
   */
  private String user;

  /**
   * Creates a builder using the parameters for configuration.
   * 
   * @param httpMethod HTTP method to use for the request
   * @param url URL that has already has already been encoded. Please see
   *          {@link com.google.gwt.http.client.URL#encode(String)},
   *          {@link com.google.gwt.http.client.URL#encodePathSegment(String)} and
   *          {@link com.google.gwt.http.client.URL#encodeQueryString(String)} for
   *          how to do this.
   * @throws IllegalArgumentException if the httpMethod or URL are empty
   * @throws NullPointerException if the httpMethod or the URL are null
   */
  public RequestBuilder(Method httpMethod, String url) {
    this((httpMethod == null) ? null : httpMethod.toString(), url);
  }

  /**
   * Creates a builder using the parameters values for configuration.
   * 
   * @param httpMethod HTTP method to use for the request
   * @param url URL that has already has already been URL encoded. Please see
   *          {@link com.google.gwt.http.client.URL#encode(String)} and
   *          {@link com.google.gwt.http.client.URL#encodePathSegment(String)} and
   *          {@link com.google.gwt.http.client.URL#encodeQueryString(String)} for
   *          how to do this.
   * @throws IllegalArgumentException if the httpMethod or URL are empty
   * @throws NullPointerException if the httpMethod or the URL are null
   */
  protected RequestBuilder(String httpMethod, String url) {

    StringValidator.throwIfEmptyOrNull("httpMethod", httpMethod);
    StringValidator.throwIfEmptyOrNull("url", url);

    this.httpMethod = httpMethod;
    this.url = url;
  }

  /**
   * Returns the callback previously set by
   * {@link #setCallback(RequestCallback)}, or <code>null</code> if no callback
   * was set.
   */
  public RequestCallback getCallback() {
    return callback;
  }

  /**
   * Returns the value of a header previous set by
   * {@link #setHeader(String, String)}, or <code>null</code> if no such header
   * was set.
   * 
   * @param header the name of the header
   */
  public String getHeader(String header) {
    if (headers == null) {
      return null;
    }
    return headers.get(header);
  }

  /**
   * Returns the HTTP method specified in the constructor.
   */
  public String getHTTPMethod() {
    return httpMethod;
  }

  /**
   * Returns the password previously set by {@link #setPassword(String)}, or
   * <code>null</code> if no password was set.
   */
  public String getPassword() {
    return password;
  }

  /**
   * Returns the requestData previously set by {@link #setRequestData(String)},
   * or <code>null</code> if no requestData was set.
   */
  public String getRequestData() {
    return requestData;
  }

  /**
   * Returns the timeoutMillis previously set by {@link #setTimeoutMillis(int)},
   * or <code>0</code> if no timeoutMillis was set.
   */
  public int getTimeoutMillis() {
    return timeoutMillis;
  }

  /**
   * Returns the HTTP URL specified in the constructor.
   */
  public String getUrl() {
    return url;
  }

  /**
   * Returns the user previously set by {@link #setUser(String)}, or
   * <code>null</code> if no user was set.
   */
  public String getUser() {
    return user;
  }

  /**
   * Sends an HTTP request based on the current builder configuration. If no
   * request headers have been set, the header "Content-Type" will be used with
   * a value of "text/plain; charset=utf-8". You must call
   * {@link #setRequestData(String)} and {@link #setCallback(RequestCallback)}
   * before calling this method.
   * 
   * @return a {@link Request} object that can be used to track the request
   * @throws RequestException if the call fails to initiate
   * @throws NullPointerException if a request callback has not been set
   */
  public Request send() throws RequestException {
    StringValidator.throwIfNull("callback", callback);
    return doSend(requestData, callback);
  }

  /**
   * Sends an HTTP request based on the current builder configuration with the
   * specified data and callback. If no request headers have been set, the
   * header "Content-Type" will be used with a value of "text/plain;
   * charset=utf-8". This method does not cache <code>requestData</code> or
   * <code>callback</code>.
   * 
   * @param requestData the data to send as part of the request
   * @param callback the response handler to be notified when the request fails
   *          or completes
   * @return a {@link Request} object that can be used to track the request
   * @throws NullPointerException if <code>callback</code> <code>null</code>
   */
  public Request sendRequest(String requestData, RequestCallback callback)
      throws RequestException {
    StringValidator.throwIfNull("callback", callback);
    return doSend(requestData, callback);
  }

  /**
   * Sets the response handler for this request. This method <b>must</b> be
   * called before calling {@link #send()}.
   * 
   * @param callback the response handler to be notified when the request fails
   *          or completes
   * 
   * @throws NullPointerException if <code>callback</code> is <code>null</code>
   */
  public void setCallback(RequestCallback callback) {
    StringValidator.throwIfNull("callback", callback);

    this.callback = callback;
  }

  /**
   * Sets a request header with the given name and value. If a header with the
   * specified name has already been set then the new value overwrites the
   * current value.
   * 
   * @param header the name of the header
   * @param value the value of the header
   * 
   * @throws NullPointerException if header or value are null
   * @throws IllegalArgumentException if header or value are the empty string
   */
  public void setHeader(String header, String value) {
    StringValidator.throwIfEmptyOrNull("header", header);
    StringValidator.throwIfEmptyOrNull("value", value);

    if (headers == null) {
      headers = new HashMap<String, String>();
    }

    headers.put(header, value);
  }

  /**
   * Sets the password to use in the request URL. This is ignored if there is no
   * user specified.
   * 
   * @param password password to use in the request URL
   * 
   * @throws IllegalArgumentException if the password is empty
   * @throws NullPointerException if the password is null
   */
  public void setPassword(String password) {
    StringValidator.throwIfEmptyOrNull("password", password);

    this.password = password;
  }

  /**
   * Sets the data to send as part of this request. This method <b>must</b> be
   * called before calling {@link #send()}.
   * 
   * @param requestData the data to send as part of the request
   */
  public void setRequestData(String requestData) {
    this.requestData = requestData;
  }

  /**
   * Sets the number of milliseconds to wait for a request to complete. Should
   * the request timeout, the
   * {@link com.google.gwt.http.client.RequestCallback#onError(Request, Throwable)}
   * method will be called on the callback instance given to the
   * {@link com.google.gwt.http.client.RequestBuilder#sendRequest(String, RequestCallback)}
   * method. The callback method will receive an instance of the
   * {@link com.google.gwt.http.client.RequestTimeoutException} class as its
   * {@link java.lang.Throwable} argument.
   * 
   * @param timeoutMillis number of milliseconds to wait before canceling the
   *          request, a value of zero disables timeouts
   * 
   * @throws IllegalArgumentException if the timeout value is negative
   */
  public void setTimeoutMillis(int timeoutMillis) {
    if (timeoutMillis < 0) {
      throw new IllegalArgumentException("Timeouts cannot be negative");
    }

    this.timeoutMillis = timeoutMillis;
  }

  /**
   * Sets the user name that will be used in the request URL.
   * 
   * @param user user name to use
   * @throws IllegalArgumentException if the user is empty
   * @throws NullPointerException if the user is null
   */
  public void setUser(String user) {
    StringValidator.throwIfEmptyOrNull("user", user);

    this.user = user;
  }

  /**
   * Sets whether the cross origin request will include credentials.
   *
   * @param withCredentials whether to include credentials in XHR
   */
  public void setIncludeCredentials(boolean includeCredentials) {
    this.includeCredentials = includeCredentials;
  }

  /**
   * Sends an HTTP request based on the current builder configuration. If no
   * request headers have been set, the header "Content-Type" will be used with
   * a value of "text/plain; charset=utf-8".
   * 
   * @return a {@link Request} object that can be used to track the request
   * @throws RequestException if the call fails to initiate
   * @throws NullPointerException if request data has not been set
   * @throws NullPointerException if a request callback has not been set
   */
  private Request doSend(String requestData, final RequestCallback callback)
      throws RequestException {
    XMLHttpRequest xmlHttpRequest = XMLHttpRequest.create();

    try {
      if (user != null && password != null) {
        xmlHttpRequest.open(httpMethod, url, user, password);
      } else if (user != null) {
        xmlHttpRequest.open(httpMethod, url, user);
      } else {
        xmlHttpRequest.open(httpMethod, url);
      }
    } catch (JavaScriptException e) {
      RequestPermissionException requestPermissionException = new RequestPermissionException(
          url);
      requestPermissionException.initCause(new RequestException(e.getMessage()));
      throw requestPermissionException;
    }

    setHeaders(xmlHttpRequest);
    if (includeCredentials) {
      xmlHttpRequest.setWithCredentials(true);
    }

    final Request request = new Request(xmlHttpRequest, timeoutMillis, callback);

    // Must set the onreadystatechange handler before calling send().
    xmlHttpRequest.setOnReadyStateChange(new ReadyStateChangeHandler() {
      public void onReadyStateChange(XMLHttpRequest xhr) {
        if (xhr.getReadyState() == XMLHttpRequest.DONE) {
          xhr.clearOnReadyStateChange();
          request.fireOnResponseReceived(callback);
        }
      }
    });

    try {
      xmlHttpRequest.send(requestData);
    } catch (JavaScriptException e) {
      throw new RequestException(e.getMessage());
    }

    return request;
  }

  /*
   * Internal method that actually sets our cached headers on the underlying
   * JavaScript XmlHttpRequest object. If there are no headers set, then we set
   * the "Content-Type" to "text/plain; charset=utf-8". This is really lining us
   * up for integration with RPC.
   */
  private void setHeaders(XMLHttpRequest xmlHttpRequest)
      throws RequestException {
    if (headers != null && headers.size() > 0) {
      for (Map.Entry<String, String> header : headers.entrySet()) {
        try {
          xmlHttpRequest.setRequestHeader(header.getKey(), header.getValue());
        } catch (JavaScriptException e) {
          throw new RequestException(e.getMessage());
        }
      }
    } else {
      xmlHttpRequest.setRequestHeader("Content-Type",
          "text/plain; charset=utf-8");
    }
  }
}
