/*
 * 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.
 */

/*
 * CacheControl.java
 *
 * Created on March 5, 2007, 3:36 PM
 */

package javax.ws.rs.core;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ws.rs.ext.RuntimeDelegate;
import javax.ws.rs.ext.RuntimeDelegate.HeaderDelegate;

/**
 * An abstraction for the value of a HTTP Cache-Control response header.
 * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9">HTTP/1.1 section 14.9</a>
 */
public class CacheControl {
    private boolean _private;
    private List<String> privateFields;
    private boolean noCache;
    private List<String> noCacheFields;
    private boolean noStore;
    private boolean noTransform;
    private boolean mustRevalidate;
    private boolean proxyRevalidate;
    private int maxAge = -1;
    private int sMaxAge = -1;
    private Map<String, String> cacheExtension;
    
    private static final HeaderDelegate<CacheControl> delegate = 
            RuntimeDelegate.getInstance().createHeaderDelegate(CacheControl.class);

    
    /**
     * Create a new instance of CacheControl. The new instance will have the 
     * following default settings:
     *
     * <ul>
     * <li>private = false</li>
     * <li>noCache = false</li>
     * <li>noStore = false</li>
     * <li>noTransform = true</li>
     * <li>mustRevalidate = false</li>
     * <li>proxyRevalidate = false</li>
     * <li>An empty list of private fields</li>
     * <li>An empty list of no-cache fields</li>
     * <li>An empty list of cache extensions</li>
     * </ul>
     */
    public CacheControl() {
        _private = false;
        noCache = false;
        noStore = false;
        noTransform = true;
        mustRevalidate = false;
        proxyRevalidate = false;
    }

    /**
     * Creates a new instance of CacheControl by parsing the supplied string.
     * @param value the cache control string
     * @return the newly created CacheControl
     * @throws IllegalArgumentException if the supplied string cannot be parsed
     * or is null
     */
    public static CacheControl valueOf(String value) throws IllegalArgumentException {
        return delegate.fromString(value);
    }
    
    /**
     * Corresponds to the must-revalidate cache control directive.
     * @return true if the must-revalidate cache control directive will be included in the
     * response, false otherwise.
     * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4">HTTP/1.1 section 14.9.4</a>
     */
    public boolean isMustRevalidate() {
        return mustRevalidate;
    }

    /**
     * Corresponds to the must-revalidate cache control directive.
     * @param mustRevalidate true if the must-revalidate cache control directive should be included in the
     * response, false otherwise.
     * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4">HTTP/1.1 section 14.9.4</a>
     */
    public void setMustRevalidate(boolean mustRevalidate) {
        this.mustRevalidate = mustRevalidate;
    }

    /**
     * Corresponds to the proxy-revalidate cache control directive.
     * @return true if the proxy-revalidate cache control directive will be included in the
     * response, false otherwise.
     * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4">HTTP/1.1 section 14.9.4</a>
     */
    public boolean isProxyRevalidate() {
        return proxyRevalidate;
    }

    /**
     * Corresponds to the must-revalidate cache control directive.
     * @param proxyRevalidate true if the proxy-revalidate cache control directive should be included in the
     * response, false otherwise.
     * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4">HTTP/1.1 section 14.9.4</a>
     */
    public void setProxyRevalidate(boolean proxyRevalidate) {
        this.proxyRevalidate = proxyRevalidate;
    }

    /**
     * Corresponds to the max-age cache control directive.
     * @return the value of the max-age cache control directive, -1 if the directive is disabled.
     * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3">HTTP/1.1 section 14.9.3</a>
     */
    public int getMaxAge() {
        return maxAge;
    }

    /**
     * Corresponds to the max-age cache control directive.
     * @param maxAge the value of the max-age cache control directive, a value of -1 will disable the directive.
     * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3">HTTP/1.1 section 14.9.3</a>
     */
    public void setMaxAge(int maxAge) {
        this.maxAge = maxAge;
    }

    /**
     * Corresponds to the s-maxage cache control directive.
     * @return the value of the s-maxage cache control directive, -1 if the directive is disabled.
     * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3">HTTP/1.1 section 14.9.3</a>
     */
    public int getSMaxAge() {
        return sMaxAge;
    }

    /**
     * Corresponds to the s-maxage cache control directive.
     * @param sMaxAge the value of the s-maxage cache control directive, a value of -1 will disable the directive.
     * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3">HTTP/1.1 section 14.9.3</a>
     */
    public void setSMaxAge(int sMaxAge) {
        this.sMaxAge = sMaxAge;
    }

    /**
     * Corresponds to the value of the no-cache cache control directive.
     * @return a mutable list of field-names that will form the value of the no-cache cache control directive.
     * An empty list results in a bare no-cache directive.
     * @see #isNoCache
     * @see #setNoCache
     * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP/1.1 section 14.9.1</a>
     */
    public List<String> getNoCacheFields() {
        if (noCacheFields == null)
            noCacheFields = new ArrayList<String>();
        return noCacheFields;
    }

    /**
     * Corresponds to the no-cache cache control directive.
     * @param noCache true if the no-cache cache control directive should be included in the
     * response, false otherwise.
     * @see #getNoCacheFields
     * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP/1.1 section 14.9.1</a>
     */
    public void setNoCache(boolean noCache) {
        this.noCache = noCache;
    }

    /**
     * Corresponds to the no-cache cache control directive.
     * @return true if the no-cache cache control directive will be included in the
     * response, false otherwise.
     * @see #getNoCacheFields
     * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP/1.1 section 14.9.1</a>
     */
    public boolean isNoCache() {
        return noCache;
    }

    /**
     * Corresponds to the private cache control directive.
     * @return true if the private cache control directive will be included in the
     * response, false otherwise.
     * @see #getPrivateFields
     * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP/1.1 section 14.9.1</a>
     */
    public boolean isPrivate() {
        return _private;
    }

    /**
     * Corresponds to the value of the private cache control directive.
     * @return a mutable list of field-names that will form the value of the private cache control directive.
     * An empty list results in a bare no-cache directive.
     * @see #isPrivate
     * @see #setPrivate
     * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP/1.1 section 14.9.1</a>
     */
    public List<String> getPrivateFields() {
        if (privateFields == null)
            privateFields = new ArrayList<String>();
        return privateFields;
    }

    /**
     * Corresponds to the private cache control directive.
     * @param _private true if the private cache control directive should be included in the
     * response, false otherwise.
     * @see #getPrivateFields
     * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP/1.1 section 14.9.1</a>
     */
    public void setPrivate(boolean _private) {
        this._private = _private;
    }

    /**
     * Corresponds to the no-transform cache control directive.
     * @return true if the no-transform cache control directive will be included in the
     * response, false otherwise.
     * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.5">HTTP/1.1 section 14.9.5</a>
     */
    public boolean isNoTransform() {
        return noTransform;
    }

    /**
     * Corresponds to the no-transform cache control directive.
     * @param noTransform true if the no-transform cache control directive should be included in the
     * response, false otherwise.
     * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.5">HTTP/1.1 section 14.9.5</a>
     */
    public void setNoTransform(boolean noTransform) {
        this.noTransform = noTransform;
    }

    /**
     * Corresponds to the no-store cache control directive.
     * @return true if the no-store cache control directive will be included in the
     * response, false otherwise.
     * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.2">HTTP/1.1 section 14.9.2</a>
     */
    public boolean isNoStore() {
        return noStore;
    }

    /**
     * Corresponds to the no-store cache control directive.
     * @param noStore true if the no-store cache control directive should be included in the
     * response, false otherwise.
     * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.2">HTTP/1.1 section 14.9.2</a>
     */
    public void setNoStore(boolean noStore) {
        this.noStore = noStore;
    }

    /**
     * Corresponds to a set of extension cache control directives.
     * @return a mutable map of cache control extension names and their values.
     * If a key has a null value, it will appear as a bare directive. If a key has
     * a value that contains no whitespace then the directive will appear as
     * a simple name=value pair. If a key has a value that contains whitespace 
     * then the directive will appear as a quoted name="value" pair.
     * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.6">HTTP/1.1 section 14.9.6</a>
     */
    public Map<String, String> getCacheExtension() {
        if (cacheExtension == null)
            cacheExtension = new HashMap<String, String>();
        return cacheExtension;
    }

    /**
     * Convert the cache control to a string suitable for use as the value of the
     * corresponding HTTP header.
     * @return a stringified cache control
     */
    @Override
    public String toString() {
        return delegate.toString(this);
    }

    /**
     * Generate hash code from cache control properties.
     * @return the hashCode
     */
    @Override
    public int hashCode() {
        int hash = 7;
        hash = 41 * hash + (this._private ? 1 : 0);
        hash = 41 * hash + (this.privateFields != null ? this.privateFields.hashCode() : 0);
        hash = 41 * hash + (this.noCache ? 1 : 0);
        hash = 41 * hash + (this.noCacheFields != null ? this.noCacheFields.hashCode() : 0);
        hash = 41 * hash + (this.noStore ? 1 : 0);
        hash = 41 * hash + (this.noTransform ? 1 : 0);
        hash = 41 * hash + (this.mustRevalidate ? 1 : 0);
        hash = 41 * hash + (this.proxyRevalidate ? 1 : 0);
        hash = 41 * hash + this.maxAge;
        hash = 41 * hash + this.sMaxAge;
        hash = 41 * hash + (this.cacheExtension != null ? this.cacheExtension.hashCode() : 0);
        return hash;
    }

    /**
     * Compares obj to this cache control to see if they are the same 
     * considering all property values.
     * @param obj the object to compare to
     * @return true if the two cache controls are the same, false otherwise.
     */
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final CacheControl other = (CacheControl) obj;
        if (this._private != other._private) {
            return false;
        }
        if (this.privateFields != other.privateFields && (this.privateFields == null || !this.privateFields.equals(other.privateFields))) {
            return false;
        }
        if (this.noCache != other.noCache) {
            return false;
        }
        if (this.noCacheFields != other.noCacheFields && (this.noCacheFields == null || !this.noCacheFields.equals(other.noCacheFields))) {
            return false;
        }
        if (this.noStore != other.noStore) {
            return false;
        }
        if (this.noTransform != other.noTransform) {
            return false;
        }
        if (this.mustRevalidate != other.mustRevalidate) {
            return false;
        }
        if (this.proxyRevalidate != other.proxyRevalidate) {
            return false;
        }
        if (this.maxAge != other.maxAge) {
            return false;
        }
        if (this.sMaxAge != other.sMaxAge) {
            return false;
        }
        if (this.cacheExtension != other.cacheExtension && (this.cacheExtension == null || !this.cacheExtension.equals(other.cacheExtension))) {
            return false;
        }
        return true;
    }
    
}
