/*********************************************************************************************************************
 * Copyright (c) 2008, 2013 Empolis Information Management GmbH and brox IT Solutions GmbH. All rights reserved. This
 * program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which
 * accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html
 *********************************************************************************************************************/
package org.eclipse.smila.http.client;

import java.io.IOException;
import java.io.InputStream;

import org.apache.http.params.HttpParams;
import org.eclipse.smila.datamodel.Any;
import org.eclipse.smila.datamodel.AnyMap;
import org.eclipse.smila.datamodel.AnySeq;
import org.eclipse.smila.datamodel.Record;

/**
 * Interface for SMILA HTTP Rest Client helpers. See {@link org.eclipse.smila.http.client.impl.DefaultRestClient} for
 * the standard implementation.
 * <p>
 * A <tt>RestClient</tt> always contains an <a href="http://hc.apache.org/httpcomponents-client-ga/index.html">Apache
 * HttpClient</a> to handle the actual HTTP communication. For documentation on classes and interfaces coming directly
 * from these libraries see the following JavaDocs:
 * <ul>
 * <li><a href="http://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/index.html">HttpCore</a>
 * <li><a href="http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/index.html">HttpClient</a>
 * </ul>
 * <p>
 * Note that all resource strings given to the methods must be correctly URL-encoded. For incorrectly encoded resources
 * a {@link IllegalArgumentException} is thrown.
 * <p>
 * Currently, all SMILA APIs return a JSON object as their result (if any), i.e. the result string starts with "{" and
 * ends with "}". Consequently, most <tt>RestClient</tt> methods return an {@link AnyMap} object. If the actual result
 * is <em>not</em> a JSON object but a JSON array ("[...]") or a simple value, when one of these methods is used, the
 * result will be wrapped in an {@link AnyMap} object with a single key <tt>result</tt>. The more generic
 * <tt>invoke(...)</tt> methods return the original result as is.
 * <p>
 * Use {@link ResourceHelper} to get the correct resource locations. See {@link TaskManagerClientHelper} for resources
 * needed by workers that want to communicate with the TaskManager using the HTTP interface.
 * 
 * See <a href="http://wiki.eclipse.org/SMILA/Documentation/HowTo/How_to_access_the_REST_API_with_the_RestClient">How to
 * access the REST API with the RestClient</a> for more information.
 */
public interface RestClient {

  /**
   * Get the base URL of the SMILA server this clients talks to, for example <tt>http://localhost:8080</tt>.
   * 
   * @return the base URL.
   */
  String getHostAndPort();

  /**
   * Sets a parameter at the underlying Apache HttpClient client object. See <a href=
   * "http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/params/AllClientPNames.html"
   * >org.apache.http.client.params.AllClientPNames</a> for links to names of possible parameters and the expected value
   * types.
   * 
   * @param name
   *          the HttpClient parameter name.
   * @param value
   *          the HttpClient parameter value.
   */
  void setClientParameter(final String name, final Object value);

  /**
   * Sets authentication parameters at the underlying Apache HttpClient client object.
   * 
   * @param user
   *          the user name used for authentication.
   * @param password
   *          the password used for authentication.
   */
  void setAuthParameters(final String user, final String password);

  /** shutdown this client. Currently running requests may be aborted. */
  void shutdown();

  /**
   * Do a GET request. Query parameters can be added to the <tt>resource</tt> string after a '?' character.
   * 
   * @param resource
   *          the API resource to call, e.g. <tt>/smila</tt>. Can contain additional URL parameters, e.g.
   *          <tt>...?returnDetails=true</tt>.
   * @return the result object, if a JSON result was returned, else <tt>null</tt>.
   * @throws RestException
   *           on errors reported by the SMILA server.
   * @throws IOException
   *           on all kinds of communication problems or data conversion errors.
   */
  AnyMap get(final String resource) throws RestException, IOException;

  /**
   * Do a GET request with parameters.
   * 
   * @param resource
   *          the API resource to call, e.g. <tt>/smila</tt>.
   * @param parameters
   *          query parameters for the rest call.
   * @return the result object, if a JSON result was returned, else <tt>null</tt>.
   * @throws RestException
   *           on errors reported by the SMILA server.
   * @throws IOException
   *           on all kinds of communication problems or data conversion errors.
   */
  AnyMap get(String resource, AnyMap parameters) throws RestException, IOException;

  /**
   * Do a GET request on a resource that can produce a bulk response (i.e., single line JSON objects, separated by
   * newlines). Query parameters can be added to the <tt>resource</tt> string after a '?' character.
   * 
   * @param resource
   *          the API resource to call, e.g. <tt>/smila</tt>. Can contain additional URL parameters, e.g.
   *          <tt>...?returnDetails=true</tt>.
   * @return a {@link BulkResponse} objects that can be used to iterate over the objects contained in the response. If
   *         no result content was returned, an empty iterator will be returned.
   * @throws RestException
   *           on errors reported by the SMILA server.
   * @throws IOException
   *           on all kinds of communication problems or data conversion errors.
   */
  BulkResponse getBulk(final String resource, final HttpParams methodParams) throws IOException, RestException;

  /**
   * Do a POST request without parameters. To add parameters to POST requests, you should not use URL parameters
   * ("...?parameter=value"), but create a parameter object and use the other methods.
   * 
   * @param resource
   *          the API resource to call, e.g. <tt>/smila/jobmanager/jobs/$name</tt>.
   * @return the result object, if a JSON result was returned, else <tt>null</tt>.
   * @throws RestException
   *           on errors reported by the SMILA server.
   * @throws IOException
   *           on all kinds of communication problems or data conversion errors.
   */
  AnyMap post(final String resource) throws RestException, IOException;

  /**
   * Do a POST request with parameters. The parameters may be definitions to be added to the server (e.g. workflow, job)
   * or record metadata to be submitted to a workflow.
   * 
   * @param resource
   *          the API resource to call, e.g. <tt>/smila/jobmanager/jobs/$name</tt>.
   * @param parameters
   *          a parameter object, definition object, or record metadata.
   * @return the result object, if a JSON result was returned, else <tt>null</tt>.
   * @throws RestException
   *           on errors reported by the SMILA server.
   * @throws IOException
   *           on all kinds of communication problems or data conversion errors.
   */
  AnyMap post(final String resource, final AnyMap parameters) throws RestException, IOException;

  /**
   * Do a POST request with parameters. The parameters may be definitions to be added to the server (e.g. workflow, job)
   * or record metadata to be submitted to a workflow in string format.
   * 
   * @param resource
   *          the API resource to call, e.g. <tt>/smila/jobmanager/jobs/$name</tt>.
   * @param parameters
   *          a parameter object, definition object, or record metadata as a string
   * @param encoding
   *          the encosing of the parameters string
   * @param contentType
   *          the contentType of the parameters
   * @return the result object, if a JSON result was returned, else <tt>null</tt>.
   * @throws RestException
   *           on errors reported by the SMILA server.
   * @throws IOException
   *           on all kinds of communication problems or data conversion errors.
   */
  AnyMap post(final String resource, final String parameters, final String encoding, final String contentType)
    throws RestException, IOException;

  /**
   * Do a POST request with parameters and attachments. Usually, parameters are record metadata and attachments are the
   * original binary documents.
   * 
   * @param resource
   *          the API resource to call, e.g. <tt>/smila/job/$name/record</tt>.
   * @param parameters
   *          a parameter object, usually record metadata.
   * @param attachments
   *          record attachments.
   * @return the result object, if a JSON result was returned, else <tt>null</tt>.
   * @throws RestException
   *           on errors reported by the SMILA server.
   * @throws IOException
   *           on all kinds of communication problems or data conversion errors.
   */
  AnyMap post(final String resource, final AnyMap parameters, final Attachments attachments) throws RestException,
    IOException;

  /**
   * Do a POST request with a record (may contain attachments) as input.
   * 
   * @param resource
   *          the API resource to call, e.g. <tt>/smila/job/$name/record</tt>.
   * @param record
   *          record metadata and attachments
   * @return the result object, if a JSON result was returned, else <tt>null</tt>.
   * @throws RestException
   *           on errors reported by the SMILA server.
   * @throws IOException
   *           on all kinds of communication problems or data conversion errors.
   */
  AnyMap post(final String resource, final Record record) throws RestException, IOException;

  /**
   * Do a POST request with a record as input. Return body and fill outParam with response header fields
   * 
   * @param resource
   *          the API resource to call, e.g. <tt>/smila/job/$name/record</tt>.
   * @param record
   *          record metadata
   * @param responseHeaderFields
   *          AnyMap which will be populated with the response header fields
   * @return the result object, if a JSON result was returned, else <tt>null</tt>.
   * @throws RestException
   *           on errors reported by the SMILA server.
   * @throws IOException
   *           on all kinds of communication problems or data conversion errors.
   */
  AnyMap postWithResponseHeader(final String resource, final Record record, AnyMap responseHeaderFields)
    throws RestException, IOException;

  /**
   * Do a PUT request with parameters. For example, the parameters may describe an object to write the ObjectStore.
   * 
   * @param resource
   *          the API resource to call, e.g. <tt>/smila/store/$name/$id</tt>.
   * @param parameters
   *          a parameter object, definition object, or record metadata.
   * @return the result object, if a JSON result was returned, else <tt>null</tt>.
   * @throws RestException
   *           on errors reported by the SMILA server.
   * @throws IOException
   *           on all kinds of communication problems or data conversion errors.
   */
  AnyMap put(final String resource, final AnyMap parameters) throws RestException, IOException;

  /**
   * Do a PUT request with a record as input, however, only the record metadata is used in the request, as PUT requests
   * cannot contain attachments.
   * 
   * @param resource
   *          the API resource to call, e.g. <tt>/smila/store/$name/$id</tt>.
   * @param record
   *          record metadata. Attachments are ignored.
   * @return the result object, if a JSON result was returned, else <tt>null</tt>.
   * @throws RestException
   *           on errors reported by the SMILA server.
   * @throws IOException
   *           on all kinds of communication problems or data conversion errors.
   */
  AnyMap put(final String resource, final Record record) throws RestException, IOException;

  /**
   * Do a DELETE request. Query parameters can be added to the <tt>resource</tt> string after a '?' character.
   * 
   * @param resource
   *          the API resource to call, e.g. <tt>/smila/store/$name</tt>. Can contain additional URL parameters, e.g.
   *          <tt>...?returnDetails=true</tt>.
   * @return the result object, if a JSON result was returned, else <tt>null</tt>.
   * @throws RestException
   *           on errors reported by the SMILA server.
   * @throws IOException
   *           on all kinds of communication problems or data conversion errors.
   */
  AnyMap delete(final String resource) throws RestException, IOException;

  /**
   * Do a DELETE request with parameters. For example the parameters might describe a record to delete.
   * 
   * @param resource
   *          the API resource to call, e.g. <tt>/smila/job/$jobname/record</tt>.
   * @param parameters
   *          a parameter object or record metadata to be attached
   * @return the result object, if a JSON result was returned, else <tt>null</tt>.
   * @throws RestException
   *           on errors reported by the SMILA server.
   * @throws IOException
   *           on all kinds of communication problems or data conversion errors.
   */
  AnyMap delete(final String resource, final AnyMap parameters) throws RestException, IOException;

  /**
   * Generic method to invoke an API resource and set special HttpClient parameters for this call only. See <a href=
   * "http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/params/AllClientPNames.html"
   * >org.apache.http.client.params.AllClientPNames</a> for links to names of possible parameters and the expected value
   * types.
   * 
   * @param method
   *          the HTTP method to use
   * @param resource
   *          the API resource to call, e.g. <tt>/smila/job/$name/record</tt>. Can contain URL parameters for GET and
   *          DELETE calls.
   * @param parameters
   *          a parameter object, usually record metadata, may be null.
   * @param attachments
   *          record attachments, may be null.
   * @param httpParams
   *          HttpClient parameters for this call, may be null.
   * @return the result object, if a JSON result was returned, else <tt>null</tt>.
   * @throws RestException
   *           on errors reported by the SMILA server.
   * @throws IOException
   *           on all kinds of communication problems or data conversion errors.
   */
  Any invoke(final HttpMethod method, final String resource, final AnyMap parameters,
    final Attachments attachments, final HttpParams httpParams) throws RestException, IOException;

  /**
   * Generic method to invoke an API resource and set special HttpClient parameters for this call only. See <a href=
   * "http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/params/AllClientPNames.html"
   * >org.apache.http.client.params.AllClientPNames</a> for links to names of possible parameters and the expected value
   * types.
   * 
   * @param method
   *          the HTTP method to use
   * @param resource
   *          the API resource to call, e.g. <tt>/smila/job/$name/record</tt>. Can contain URL parameters for GET and
   *          DELETE calls.
   * @param parameters
   *          a parameter object, usually record metadata, may be null.
   * @param attachments
   *          record attachments, may be null.
   * @param httpParams
   *          HttpClient parameters for this call, may be null.
   * @return the result object, if a JSON result was returned, else <tt>null</tt>.
   * @throws RestException
   *           on errors reported by the SMILA server.
   * @throws IOException
   *           on all kinds of communication problems or data conversion errors.
   */
  Any invoke(final HttpMethod method, final String resource, final AnySeq parameters,
    final Attachments attachments, final HttpParams httpParams) throws RestException, IOException;

  /**
   * Invoke an API resource using content from a input stream containing JSON and set special HttpClient parameters for
   * this call only. See <a href=
   * "http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/params/AllClientPNames.html"
   * >org.apache.http.client.params.AllClientPNames</a> for links to names of possible parameters and the expected value
   * types.
   * 
   * @param method
   *          the HTTP method to use
   * @param resource
   *          the API resource to call, e.g. <tt>/smila/job/$name/record</tt>. Can contain URL parameters for GET and
   *          DELETE calls.
   * @param inputStream
   *          an input stream with valid JSON data.
   * @param httpParams
   *          HttpClient parameters for this call, may be null.
   * @return the result object, if a JSON result was returned, else <tt>null</tt>.
   * @throws RestException
   *           on errors reported by the SMILA server.
   * @throws IOException
   *           on all kinds of communication problems or data conversion errors.
   */
  Any invoke(final HttpMethod method, final String resource, final InputStream inputStream,
    final HttpParams httpParams) throws RestException, IOException;

  /**
   * Invoke an API resource using content from a input stream containing the specified content type and set special
   * HttpClient parameters for this call only. See <a href=
   * "http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/params/AllClientPNames.html"
   * >org.apache.http.client.params.AllClientPNames</a> for links to names of possible parameters and the expected value
   * types.
   * 
   * @param method
   *          the HTTP method to use
   * @param resource
   *          the API resource to call, e.g. <tt>/smila/job/$name/record</tt>. Can contain URL parameters for GET and
   *          DELETE calls.
   * @param inputStream
   *          an input stream with data of the specified content type
   * @param contentType
   *          content type of data.
   * @param httpParams
   *          HttpClient parameters for this call, may be null.
   * @return the result object, if a JSON result was returned, else <tt>null</tt>.
   * @throws RestException
   *           on errors reported by the SMILA server.
   * @throws IOException
   *           on all kinds of communication problems or data conversion errors.
   */
  Any invoke(final HttpMethod method, final String resource, final InputStream inputStream, String contentType,
    final HttpParams httpParams) throws RestException, IOException;

}
