/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 *
 */
package org.apache.asyncweb.common;

import java.util.concurrent.TimeUnit;

/**
 * Default cookie implementation.
 *
 * @author The Apache MINA Project (dev@mina.apache.org)
 * @version $Rev$, $Date$
 */
public class DefaultCookie implements MutableCookie {

    private static final long serialVersionUID = 5713305385740914300L;

    private final String name;

    private String value;

    private String domain;

    private String path;

    private String comment;

    private boolean secure;

    private int version = 0;

    private int maxAge = -1;
    
    private long createdDate = System.currentTimeMillis();

    /**
     * Creates a new cookie with a specified name.
     *
     * @param name the name of the new cookie
     */
    public DefaultCookie(String name) {
        if (name == null) {
    		throw new IllegalArgumentException("name can NOT be null");
        }

        this.name = name;
    }
    
    /**
     * Creates a new cookie with a specified name and value.
     * 
     * @param name  the name of the new cookie
     * @param value  the default value of the new cookie
     */
    public DefaultCookie(String name, String value) {
        this(name);
    	this.value = value;
    }
    
    /**
     * Creates a new cookie based on the values of the specified <tt>Cookie</tt>.
     * 
     * @param cookie  the <tt>Cookie</tt> object from which the new
     *                  instance of <tt>DefaultCookie</tt> will copy its values
     */
    public DefaultCookie(Cookie cookie) {
        this(cookie.getName());
        this.comment = cookie.getComment();
        this.createdDate = cookie.getCreatedDate();
        this.domain = cookie.getDomain();
        this.maxAge = cookie.getMaxAge();
        this.path = cookie.getPath();
        this.secure = cookie.isSecure();
        this.value = cookie.getValue();
        this.version = cookie.getVersion();
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public String getDomain() {
        return domain;
    }

    public void setDomain(String domain) {
        this.domain = domain;
    }

    public int getMaxAge() {
        return maxAge;
    }

    public void setMaxAge(int maxAge) {
        this.maxAge = maxAge;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public boolean isSecure() {
        return secure;
    }

    public void setSecure(boolean secure) {
        this.secure = secure;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public int getVersion() {
        return version;
    }

    public void setVersion(int version) {
        this.version = version;
    }

    public String getName() {
        return name;
    }
    
    public long getCreatedDate() {
    	return createdDate;
    }
    
    public void setCreatedDate(long createdDate) {
		this.createdDate = createdDate;
	}

    public long getExpirationDate() {
    	return createdDate + TimeUnit.SECONDS.toMillis(maxAge);
    }
    
    /**
     * Builds the hash code of this object based on the <em>name</em>, <em>path</em>, and <em>domain</em> fields.
     */
    @Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((domain == null) ? 0 : domain.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + ((path == null) ? 0 : path.hashCode());
		return result;
	}

    /**
     * Determines the equality of this cookie to another Cookie object based on the <em>name</em>, <em>path</em>, and
     * <em>domain</em> fields of the cookies. 
     */
    @Override
    public boolean equals(Object o) {
        if (o == this) {
            return true;
        }

        if (!(o instanceof Cookie)) {
            return false;
        }

        Cookie that = (Cookie) o;
        if (!name.equals(that.getName())) {
            return false;
        }

        if (path == null) {
            if (that.getPath() != null) {
                return false;
            }
        } else if (!path.equals(that.getPath())) {
            return false;
        }

        if (domain == null) {
            if (that.getDomain() != null) {
                return false;
            }
        } else if (!domain.equals(that.getDomain())) {
            return false;
        }

        return true;
    }

    public int compareTo(Cookie o) {
        int answer;

        // Compare the name first.
        answer = name.compareTo(o.getName());
        if (answer != 0) {
            return answer;
        }

        // and then path
        if (path == null) {
            if (o.getPath() != null) {
                answer = -1;
            } else {
                answer = 0;
            }
        } else {
            answer = path.compareTo(o.getPath());
        }

        if (answer != 0) {
            return answer;
        }

        // and then domain
        if (domain == null) {
            if (o.getDomain() != null) {
                answer = -1;
            } else {
                answer = 0;
            }
        } else {
            answer = domain.compareTo(o.getDomain());
        }

        return answer;
    }

    @Override
    public String toString() {
        return "name=" + getName() + " value=" + getValue() + " domain="
                + getDomain() + " path=" + getPath() + " maxAge=" + getMaxAge()
                + " secure=" + isSecure();
    }
}
