package org.binxance.api;

import java.util.Map;
import java.util.function.Function;

import org.binxance.api.annotations.ServiceMethod.Type;

/**
 * Abstraction of an HTTP request which support both
 * request/response and streaming models
 */
public interface IRequest {

	/**
	 * Base URL of the request - Optional.  
	 * If not specified the entirety of the URL should be specified in the relative path
	 * Note: One of base/relative must be specified
	 * @param url
	 */
	public void setBaseUrl(String url);

	/**
	 * Relative URL of the request - Optional.  
	 * If not specified the entirety of the URL should be specified in the baseURL
	 * Note: One of base/relative must be specified
	 * @param url
	 */
	public void setRelativeUrl(String url);

	/**
	 * Set the method of the request (POST,PUT,DELETE,..).  
	 * Optional - GET should be the default if not otherwise specified
	 * @param type
	 */
	public void setMethod(Type type);
	
	/**
	 * Add a parameter to the Request
	 * Note:  Current implementation only support query string parameters
	 * @param name
	 * @param value
	 */
	public void addParameter(String name, String value);

	/**
	 * Access the parameters set for the request
	 * @return
	 */
	public Map<String,String> getParameters();
	
	/**
	 * Add a header to the request
	 * @param name
	 * @param value
	 */
	public void addHeader(String name, String value);

	/**
	 * Execute the request as a typical request/response model
	 * @return IRestResponse - which will provide access to the HTTP status code and response bod (if any)
	 * @throws Exception
	 */
	public IRestResponse execute() throws Exception;
	
	/**
	 * Execute the request as a streaming request (WebSocket) returning a callback to both listen and administer the stream/connection
	 * @param adapter A type adapter which is capable of transforming the response from the typical String/Bytes to a given type
	 * @return IStreamingResponse for callbacks and administration of the stream
	 * @throws Exception
	 */
	public <T> IStreamingResponse<T> stream(Function<String,T> adapter) throws Exception;

}