/*
 * 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 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. Entities of type {@link GenericEntity} 
     * will be unwrapped. 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(Status 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
     */
    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. Wrap the 
     * actual entity with {@link GenericEntity} if the generic type should be
     * preserved.
     * 
     * @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. If
     * required, wrap the actual entity with {@link GenericEntity} to preserve
     * the generic type.
     * 
     * @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. If
     * required, wrap the actual entity with {@link GenericEntity} to preserve
     * the generic type.
     * 
     * @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. If
     * required, wrap the actual entity with {@link GenericEntity} to preserve
     * the generic type.
     * 
     * @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
     */
    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
     */
    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
     */
    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
     */
    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
     */
    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
     * @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
         */
        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(Status status) {
            if (status == null)
                throw new IllegalArgumentException();
            return status(status.getStatusCode());
        };
        
        /**
         * Set the entity on the ResponseBuilder. If required, wrap the actual
         * entity with {@link GenericEntity} to preserve the generic type.
         * 
         * @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
         * @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
         * @return the updated ResponseBuilder
         * @throws IllegalArgumentException if type cannot be parsed
         */
        public abstract ResponseBuilder type(String type);
        
        /**
         * Set representation metadata on the ResponseBuilder.
         * 
         * 
         * @param variant metadata of the response entity
         * @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
         * @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
         * @return the updated ResponseBuilder
         */
        public abstract ResponseBuilder language(String language);
        
        /**
         * Set the language on the ResponseBuilder.
         * 
         * 
         * @param language the language of the response entity
         * @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}).
         * @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.
         * @return the updated ResponseBuilder
         */
        public abstract ResponseBuilder contentLocation(URI location);
        
        /**
         * Set an entity tag on the ResponseBuilder.
         * 
         * @param tag the entity tag
         * @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.
         * @return the updated ResponseBuilder
         */
        public abstract ResponseBuilder tag(String tag);
        
        /**
         * Set the last modified date on the ResponseBuilder.
         * 
         * 
         * @param lastModified the last modified date
         * @return the updated ResponseBuilder
         */
        public abstract ResponseBuilder lastModified(Date lastModified);
        
        /**
         * Set the cache control data on the ResponseBuilder.
         * 
         * 
         * @param cacheControl the 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
         * @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);
    }
    
    /**
     * 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.
     */
    public enum Status {
        /**
         * 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;
        
        /**
         * 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};
        
        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
         */
        @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;
        }
    }
}
