/*
 *  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)
 */
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();
    }
}
