/*
 * The contents of this file are subject to the terms
 * of the Common Development and Distribution License
 * (the "License").  You may not use this file except
 * in compliance with the License.
 *
 * You can obtain a copy of the license at
 * http://www.opensource.org/licenses/cddl1.php
 * See the License for the specific language governing
 * permissions and limitations under the License.
 */

/*
 * Response.java
 *
 * Created on April 18, 2007, 9:00 AM
 *
 */

package javax.ws.rs.core;

import java.net.URI;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import javax.ws.rs.ext.RuntimeDelegate;

/**
 * Defines the contract between a returned instance and the runtime when
 * an application needs to provide metadata to the runtime. An application
 * class can extend this class directly or can use one of the static 
 * methods to create an instance using a ResponseBuilder.
 * 
 * Several methods have parameters of type URI, {@link UriBuilder} provides
 * convenient methods to create such values as does 
 * {@link <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/net/URI.html#create(java.lang.String)">URI.create()</a>}.
 * 
 * @see Response.ResponseBuilder
 */
public abstract class Response {
    
    /**
     * Protected constructor, use one of the static methods to obtain a 
     * {@link ResponseBuilder} instance and obtain a Response from that.
     */
    protected Response() {}
    
    
    /**
     * Return the response entity. The response will be serialized using a
     * MessageBodyWriter for either the class of the entity or, in the case of
     * {@link GenericEntity}, the value of {@link GenericEntity#getRawType()}.
     * @return an object instance or null if there is no entity
     * @see javax.ws.rs.ext.MessageBodyWriter
     */
    public abstract Object getEntity();
    
    /**
     * Get the status code associated with the response.
     * @return the response status code or -1 if the status was not set.  
     */
    public abstract int getStatus();

    /**
     * Get metadata associated with the response as a map. The returned map
     * may be subsequently modified by the JAX-RS runtime. Values will be
     * serialized using a {@link javax.ws.rs.ext.RuntimeDelegate.HeaderDelegate}
     * if one is available via
     * {@link javax.ws.rs.ext.RuntimeDelegate#createHeaderDelegate(java.lang.Class)}
     * for the class of the value or using the values {@code toString} method if a 
     * header delegate is not available.
     * @return response metadata as a map
     */
    public abstract MultivaluedMap<String, Object> getMetadata();
    
    /**
     * Create a new ResponseBuilder by performing a shallow copy of an
     * existing Response. The returned builder has its own metadata map but
     * entries are simply references to the keys and values contained in the
     * supplied Response metadata map.
     * @param response a Response from which the status code, entity and metadata
     * will be copied
     * @return a new ReponseBuilder
     */
    public static ResponseBuilder fromResponse(Response response) {
        ResponseBuilder b = status(response.getStatus());
        b.entity(response.getEntity());
        for (String headerName: response.getMetadata().keySet()) {
            List<Object> headerValues = response.getMetadata().get(headerName);
            for (Object headerValue: headerValues) {
                b.header(headerName, headerValue);
            }
        }
        return b;
    }
    
    /**
     * Create a new ResponseBuilder with the supplied status.
     * @param status the response status
     * @return a new ResponseBuilder
     * @throws IllegalArgumentException if status is null
     */
    public static ResponseBuilder status(StatusType status) {
        ResponseBuilder b = ResponseBuilder.newInstance();
        b.status(status);
        return b;
    }

    /**
     * Create a new ResponseBuilder with the supplied status.
     * @param status the response status
     * @return a new ResponseBuilder
     * @throws IllegalArgumentException if status is less than 100 or greater
     * than 599.
     */
    public static ResponseBuilder status(int status) {
        ResponseBuilder b = ResponseBuilder.newInstance();
        b.status(status);
        return b;
    }

    /**
     * Create a new ResponseBuilder with an OK status.
     * 
     * @return a new ResponseBuilder
     */
    public static ResponseBuilder ok() {
        ResponseBuilder b = status(Status.OK);
        return b;
    }

    /**
     * Create a new ResponseBuilder that contains a representation. It is the
     * callers responsibility to wrap the actual entity with
     * {@link GenericEntity} if preservation of its generic type is required.
     * 
     * @param entity the representation entity data
     * @return a new ResponseBuilder
     */
    public static ResponseBuilder ok(Object entity) {
        ResponseBuilder b = ok();
        b.entity(entity);
        return b;
    }

    /**
     * Create a new ResponseBuilder that contains a representation. It is the
     * callers responsibility to wrap the actual entity with
     * {@link GenericEntity} if preservation of its generic type is required.
     * 
     * @param entity the representation entity data
     * @param type the media type of the entity
     * @return a new ResponseBuilder
     */
    public static ResponseBuilder ok(Object entity, MediaType type) {
        ResponseBuilder b = ok();
        b.entity(entity);
        b.type(type);
        return b;
    }

    /**
     * Create a new ResponseBuilder that contains a representation. It is the
     * callers responsibility to wrap the actual entity with
     * {@link GenericEntity} if preservation of its generic type is required.
     * 
     * @param entity the representation entity data
     * @param type the media type of the entity
     * @return a new ResponseBuilder
     */
    public static ResponseBuilder ok(Object entity, String type) {
        ResponseBuilder b = ok();
        b.entity(entity);
        b.type(type);
        return b;
    }

    /**
     * Create a new ResponseBuilder that contains a representation. It is the
     * callers responsibility to wrap the actual entity with
     * {@link GenericEntity} if preservation of its generic type is required.
     * 
     * @param entity the representation entity data
     * @param variant representation metadata
     * @return a new ResponseBuilder
     */
    public static ResponseBuilder ok(Object entity, Variant variant) {
        ResponseBuilder b = ok();
        b.entity(entity);
        b.variant(variant);
        return b;
    }

    /**
     * Create a new ResponseBuilder with an server error status.
     * 
     * @return a new ResponseBuilder
     */
    public static ResponseBuilder serverError() {
        ResponseBuilder b = status(Status.INTERNAL_SERVER_ERROR);
        return b;
    }

    /**
     * Create a new ResponseBuilder for a created resource, set the location
     * header using the supplied value.
     * 
     * @param location the URI of the new resource. If a relative URI is 
     * supplied it will be converted into an absolute URI by resolving it
     * relative to the request URI (see {@link UriInfo#getRequestUri}).
     * @return a new ResponseBuilder
     * @throws java.lang.IllegalArgumentException if location is null
     */
    public static ResponseBuilder created(URI location) {
        ResponseBuilder b = status(Status.CREATED).location(location);
        return b;
    }

    /**
     * Create a new ResponseBuilder for an empty response.
     * 
     * @return a new ResponseBuilder
     */
    public static ResponseBuilder noContent() {
        ResponseBuilder b = status(Status.NO_CONTENT);
        return b;
    }

    /**
     * Create a new ResponseBuilder with a not-modified status.
     * 
     * @return a new ResponseBuilder
     */
    public static ResponseBuilder notModified() {
        ResponseBuilder b = status(Status.NOT_MODIFIED);
        return b;
    }

    /**
     * Create a new ResponseBuilder with a not-modified status.
     * 
     * @param tag a tag for the unmodified entity
     * @return a new ResponseBuilder
     * @throws java.lang.IllegalArgumentException if tag is null
     */
    public static ResponseBuilder notModified(EntityTag tag) {
        ResponseBuilder b = notModified();
        b.tag(tag);
        return b;
    }

    /**
     * Create a new ResponseBuilder with a not-modified status
     * and a strong entity tag. This is a shortcut
     * for <code>notModified(new EntityTag(<i>value</i>))</code>.
     * 
     * @param tag the string content of a strong entity tag. The JAX-RS
     * runtime will quote the supplied value when creating the header.
     * @return a new ResponseBuilder
     * @throws java.lang.IllegalArgumentException if tag is null
     */
    public static ResponseBuilder notModified(String tag) {
        ResponseBuilder b = notModified();
        b.tag(tag);
        return b;
    }

    /**
     * Create a new ResponseBuilder for a redirection. Used in the
     * redirect-after-POST (aka POST/redirect/GET) pattern.
     * 
     * @param location the redirection URI. If a relative URI is 
     * supplied it will be converted into an absolute URI by resolving it
     * relative to the base URI of the application (see 
     * {@link UriInfo#getBaseUri}).
     * @return a new ResponseBuilder
     * @throws java.lang.IllegalArgumentException if location is null
     */
    public static ResponseBuilder seeOther(URI location) {
        ResponseBuilder b = status(Status.SEE_OTHER).location(location);
        return b;
    }

    /**
     * Create a new ResponseBuilder for a temporary redirection.
     * 
     * @param location the redirection URI. If a relative URI is 
     * supplied it will be converted into an absolute URI by resolving it
     * relative to the base URI of the application (see 
     * {@link UriInfo#getBaseUri}).
     * @return a new ResponseBuilder
     * @throws java.lang.IllegalArgumentException if location is null
     */
    public static ResponseBuilder temporaryRedirect(URI location) {
        ResponseBuilder b = status(Status.TEMPORARY_REDIRECT).location(location);
        return b;
    }

    /**
     * Create a new ResponseBuilder for a not acceptable response.
     * 
     * @param variants list of variants that were available, a null value is
     * equivalent to an empty list.
     * @return a new ResponseBuilder
     */
    public static ResponseBuilder notAcceptable(List<Variant> variants) {
        ResponseBuilder b = status(Status.NOT_ACCEPTABLE).variants(variants);
        return b;
    }
        
    /**
     * A class used to build Response instances that contain metadata instead 
     * of or in addition to an entity. An initial instance may be obtained via
     * static methods of the Response class, instance methods provide the
     * ability to set metadata. E.g. to create a response that indicates the 
     * creation of a new resource:
     * <pre>&#64;POST
     * Response addWidget(...) {
     *   Widget w = ...
     *   URI widgetId = UriBuilder.fromResource(Widget.class)...
     *   return Response.created(widgetId).build();
     * }</pre>
     * 
     * <p>Several methods have parameters of type URI, {@link UriBuilder} provides
     * convenient methods to create such values as does <code>URI.create()</code>.</p>
     * 
     * <p>Where multiple variants of the same method are provided, the type of
     * the supplied parameter is retained in the metadata of the built 
     * {@code Response}.</p>  
     * 
     */
    public static abstract class ResponseBuilder {

        /**
         * Protected constructor, use one of the static methods of
         * <code>Response</code> to obtain an instance.
         */
        protected ResponseBuilder() {}
        
        /**
         * Create a new builder instance.
         * 
         * @return a new ResponseBuilder
         */
        protected static ResponseBuilder newInstance() {
            ResponseBuilder b = RuntimeDelegate.getInstance().createResponseBuilder();
            return b;
        }
        
        /**
         * Create a Response instance from the current ResponseBuilder. The builder
         * is reset to a blank state equivalent to calling the ok method.
         * 
         * @return a Response instance
         */
        public abstract Response build();
        
        /**
         * Create a copy of the ResponseBuilder preserving its state.
         * @return a copy of the ResponseBuilder
         */
        @Override
        public abstract ResponseBuilder clone();

        /**
         * Set the status on the ResponseBuilder.
         * 
         * @param status the response status
         * @return the updated ResponseBuilder
         * @throws IllegalArgumentException if status is less than 100 or greater
         * than 599.
         */
        public abstract ResponseBuilder status(int status);
        
        /**
         * Set the status on the ResponseBuilder.
         * 
         * @param status the response status
         * @return the updated ResponseBuilder
         * @throws IllegalArgumentException if status is null
         */
        public ResponseBuilder status(StatusType status) {
            if (status == null)
                throw new IllegalArgumentException();
            return status(status.getStatusCode());
        };
        
        /**
         * Set the entity on the ResponseBuilder. It is the
         * callers responsibility to wrap the actual entity with
         * {@link GenericEntity} if preservation of its generic type is required.
         * 
         * @param entity the response entity
         * @return the updated ResponseBuilder
         */
        public abstract ResponseBuilder entity(Object entity);
        
        /**
         * Set the response media type on the ResponseBuilder.
         * 
         * @param type the media type of the response entity, if null any 
         * existing value for type will be removed
         * @return the updated ResponseBuilder
         */
        public abstract ResponseBuilder type(MediaType type);
        
        /**
         * Set the response media type on the ResponseBuilder.
         * 
         * @param type the media type of the response entity, if null any 
         * existing value for type will be removed
         * @return the updated ResponseBuilder
         * @throws IllegalArgumentException if type cannot be parsed
         */
        public abstract ResponseBuilder type(String type);
        
        /**
         * Set representation metadata on the ResponseBuilder. Equivalent to
         * setting the values of content type, content language, and content
         * encoding separately using the values of the variant properties.
         * 
         * @param variant metadata of the response entity, a null value is
         * equivalent to a variant with all null properties.
         * @return the updated ResponseBuilder
         */
        public abstract ResponseBuilder variant(Variant variant);
        
        /**
         * Add a Vary header that lists the available variants.
         * 
         * @param variants a list of available representation variants, a null
         * value will remove an existing value for vary.
         * @return the updated ResponseBuilder
         */
        public abstract ResponseBuilder variants(List<Variant> variants);

        /**
         * Set the language on the ResponseBuilder.
         * 
         * @param language the language of the response entity, if null any 
         * existing value for language will be removed
         * @return the updated ResponseBuilder
         */
        public abstract ResponseBuilder language(String language);
        
        /**
         * Set the language on the ResponseBuilder.
         * 
         * 
         * @param language the language of the response entity, if null any 
         * existing value for type will be removed
         * @return the updated ResponseBuilder
         */
        public abstract ResponseBuilder language(Locale language);
        
        /**
         * Set the location on the ResponseBuilder.
         * 
         * @param location the location. If a relative URI is 
         * supplied it will be converted into an absolute URI by resolving it
         * relative to the base URI of the application (see 
         * {@link UriInfo#getBaseUri}). If null any 
         * existing value for location will be removed.
         * @return the updated ResponseBuilder
         */
        public abstract ResponseBuilder location(URI location);
        
        /**
         * Set the content location on the ResponseBuilder.
         * 
         * @param location the content location. Relative or absolute URIs
         * may be used for the value of content location. If null any 
         * existing value for content location will be removed.
         * @return the updated ResponseBuilder
         */
        public abstract ResponseBuilder contentLocation(URI location);
        
        /**
         * Set an entity tag on the ResponseBuilder.
         * 
         * @param tag the entity tag, if null any 
         * existing entity tag value will be removed.
         * @return the updated ResponseBuilder
         */
        public abstract ResponseBuilder tag(EntityTag tag);
        
        /**
         * Set a strong entity tag on the ResponseBuilder. This is a shortcut
         * for <code>tag(new EntityTag(<i>value</i>))</code>.
         * 
         * @param tag the string content of a strong entity tag. The JAX-RS
         * runtime will quote the supplied value when creating the header. If
         * null any existing entity tag value will be removed.
         * @return the updated ResponseBuilder
         */
        public abstract ResponseBuilder tag(String tag);
        
        /**
         * Set the last modified date on the ResponseBuilder.
         * 
         * @param lastModified the last modified date, if null any existing
         * last modified value will be removed.
         * @return the updated ResponseBuilder
         */
        public abstract ResponseBuilder lastModified(Date lastModified);
        
        /**
         * Set the cache control data on the ResponseBuilder.
         * 
         * @param cacheControl the cache control directives, if null removes any
         * existing cache control directives.
         * @return the updated ResponseBuilder
         */
        public abstract ResponseBuilder cacheControl(CacheControl cacheControl);
        
        /**
         * Set the expires date on the ResponseBuilder.
         * 
         * @param expires the expiration date, if null removes any existing
         * expires value.
         * @return the updated ResponseBuilder
         */
        public abstract ResponseBuilder expires(Date expires);
        
        /**
         * Add a header to the ResponseBuilder.
         * 
         * @param name the name of the header
         * @param value the value of the header, the header will be serialized
         * using a {@link javax.ws.rs.ext.RuntimeDelegate.HeaderDelegate} if
         * one is available via
         * {@link javax.ws.rs.ext.RuntimeDelegate#createHeaderDelegate(java.lang.Class)}
         * for the class of {@code value} or using its {@code toString} method if a 
         * header delegate is not available. If {@code value} is null then all 
         * current headers of the same name will be removed.
         * @return the updated ResponseBuilder
         */
        public abstract ResponseBuilder header(String name, Object value);
        
        /**
         * Add cookies to the ResponseBuilder.
         * 
         * @param cookies new cookies that will accompany the response. A null
         * value will remove all cookies, including those added via the 
         * {@link #header(java.lang.String, java.lang.Object)} method.
         * @return the updated ResponseBuilder
         */
        public abstract ResponseBuilder cookie(NewCookie... cookies);
    }
    
    /**
     * Base interface for statuses used in responses.
     */
    public interface StatusType {
        /**
         * An enumeration representing the class of status code. Family is used
         * here since class is overloaded in Java.
         */
        public enum Family {INFORMATIONAL, SUCCESSFUL, REDIRECTION, CLIENT_ERROR, SERVER_ERROR, OTHER};
        
        /**
         * Get the associated status code
         * @return the status code
         */
        public int getStatusCode();

        /**
         * Get the class of status code
         * @return the class of status code
         */
        public Family getFamily();

        /**
         * Get the reason phrase
         * @return the reason phrase
         */
        public String getReasonPhrase();
    }
    
    /**
     * Commonly used status codes defined by HTTP, see 
     * {@link <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10">HTTP/1.1 documentation</a>}
     * for the complete list. Additional status codes can be added by applications
     * by creating an implementation of {@link StatusType}.
     */
    public enum Status implements StatusType {
        /**
         * 200 OK, see {@link <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1">HTTP/1.1 documentation</a>}.
         */
        OK(200, "OK"),
        /**
         * 201 Created, see {@link <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.2">HTTP/1.1 documentation</a>}.
         */
        CREATED(201, "Created"),
        /**
         * 202 Accepted, see {@link <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.3">HTTP/1.1 documentation</a>}.
         */
        ACCEPTED(202, "Accepted"),
        /**
         * 204 No Content, see {@link <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.5">HTTP/1.1 documentation</a>}.
         */
        NO_CONTENT(204, "No Content"),
        /**
         * 303 See Other, see {@link <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.2">HTTP/1.1 documentation</a>}.
         */
        MOVED_PERMANENTLY(301, "Moved Permanently"),
        /**
         * 303 See Other, see {@link <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4">HTTP/1.1 documentation</a>}.
         */
        SEE_OTHER(303, "See Other"),
        /**
         * 304 Not Modified, see {@link <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5">HTTP/1.1 documentation</a>}.
         */
        NOT_MODIFIED(304, "Not Modified"),
        /**
         * 307 Temporary Redirect, see {@link <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.8">HTTP/1.1 documentation</a>}.
         */
        TEMPORARY_REDIRECT(307, "Temporary Redirect"),
        /**
         * 400 Bad Request, see {@link <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1">HTTP/1.1 documentation</a>}.
         */
        BAD_REQUEST(400, "Bad Request"),
        /**
         * 401 Unauthorized, see {@link <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2">HTTP/1.1 documentation</a>}.
         */
        UNAUTHORIZED(401, "Unauthorized"),
        /**
         * 403 Forbidden, see {@link <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4">HTTP/1.1 documentation</a>}.
         */
        FORBIDDEN(403, "Forbidden"),
        /**
         * 404 Not Found, see {@link <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.5">HTTP/1.1 documentation</a>}.
         */
        NOT_FOUND(404, "Not Found"),
        /**
         * 406 Not Acceptable, see {@link <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.7">HTTP/1.1 documentation</a>}.
         */
        NOT_ACCEPTABLE(406, "Not Acceptable"),
        /**
         * 409 Conflict, see {@link <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.10">HTTP/1.1 documentation</a>}.
         */
        CONFLICT(409, "Conflict"),
        /**
         * 410 Gone, see {@link <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.11">HTTP/1.1 documentation</a>}.
         */
        GONE(410, "Gone"),
        /**
         * 412 Precondition Failed, see {@link <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.13">HTTP/1.1 documentation</a>}.
         */
        PRECONDITION_FAILED(412, "Precondition Failed"),
        /**
         * 415 Unsupported Media Type, see {@link <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.16">HTTP/1.1 documentation</a>}.
         */
        UNSUPPORTED_MEDIA_TYPE(415, "Unsupported Media Type"),
        /**
         * 500 Internal Server Error, see {@link <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.1">HTTP/1.1 documentation</a>}.
         */
        INTERNAL_SERVER_ERROR(500, "Internal Server Error"),
        /**
         * 503 Service Unavailable, see {@link <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.4">HTTP/1.1 documentation</a>}.
         */
        SERVICE_UNAVAILABLE(503, "Service Unavailable");
        
        private final int code;
        private final String reason;
        private Family family;
        
        Status(final int statusCode, final String reasonPhrase) {
            this.code = statusCode;
            this.reason = reasonPhrase;
            switch(code/100) {
                case 1: this.family = Family.INFORMATIONAL; break;
                case 2: this.family = Family.SUCCESSFUL; break;
                case 3: this.family = Family.REDIRECTION; break;
                case 4: this.family = Family.CLIENT_ERROR; break;
                case 5: this.family = Family.SERVER_ERROR; break;
                default: this.family = Family.OTHER; break;
            }
        }
        
        /**
         * Get the class of status code
         * @return the class of status code
         */
        public Family getFamily() {
            return family;
        }
        
        /**
         * Get the associated status code
         * @return the status code
         */
        public int getStatusCode() {
            return code;
        }
        
        /**
         * Get the reason phrase
         * @return the reason phrase
         */
        public String getReasonPhrase() {
            return toString();
        }
        
        /**
         * Get the reason phrase
         * @return the reason phrase
         */
        @Override
        public String toString() {
            return reason;
        }
        
        /**
         * Convert a numerical status code into the corresponding Status
         * @param statusCode the numerical status code
         * @return the matching Status or null is no matching Status is defined
         */
        public static Status fromStatusCode(final int statusCode) {
            for (Status s : Status.values()) {
                if (s.code == statusCode) {
                    return s;
                }
            }
            return null;
        }
    }
}
