/*
 * JBoss, Home of Professional Open Source
 * Copyright 2005, JBoss Inc., and individual contributors as indicated
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.jboss.cache;


/**
 * Maintains update-specific options. These will override the default options
 * for a cache.
 * @author Bela Ban
 * @version $Revision: 1.1.2.1 $
 */
public class Options {

    /** Entries in the cache are by default transient; ie. not replicated */
    public static final int TRANSIENT=1;

    /** Entries in the cache are by default replicated (asynchronously) */
    public static final int REPL_ASYNC=2;

    /** Entries in the cache are by default replicated (synchronously) */
    public static final int REPL_SYNC=3;


    /** Max number of milliseconds to wait for all responses on a synchronous replication
     * until the call returns.
     */
    long sync_repl_timeout=5000;

    /** Max number of millseconds to acquire a lock */
    long lock_acquisition_timeout=10000;

    /** Max number of miliseconds a lock is held. If this is exceeded the lock wil be automatically released.
     * Note that this is currently not used.
     */
    long lock_lease_timeout=60 * 1000;

    /** The default caching mode is asynchronous replication */
    int caching_mode=REPL_ASYNC;

    /** Whether or not to commit a transaction after this update */
    boolean commit=false;


    /**
     * Constructor for Options.
     */
    public Options() {
        super();
    }

    public Options(int caching_mode) {
        this.caching_mode=caching_mode;
    }

    public Options(int caching_mode, long sync_repl_timeout) {
        this(caching_mode);
        this.sync_repl_timeout=sync_repl_timeout;
    }

    public Options(int caching_mode, long sync_repl_timeout,
                   long lock_acquisition_timeout, long lock_lease_timeout) {
        this(caching_mode, sync_repl_timeout);
        this.lock_acquisition_timeout=lock_acquisition_timeout;
        this.lock_lease_timeout=lock_lease_timeout;
    }

    public Options(int caching_mode, long sync_repl_timeout,
                   long lock_acquisition_timeout, long lock_lease_timeout, boolean commit) {
        this(caching_mode, sync_repl_timeout, lock_acquisition_timeout, lock_lease_timeout);
        this.commit=commit;
    }

    /** Returns the current default caching mode. Possible values are
     * <ul>
     * <li>TRANSIENT
     * <li>REPL_ASYNC
     * <li>REPL_SYNC
     * <ul>
     * @return int The caching mode
     */
    int getCachingMode() {
        return caching_mode;
    }

    /** Sets the default caching mode (see {@link #setCachingMode(int)}) */
    void setCachingMode(int mode) {
        this.caching_mode=mode;
    }

    /**
     * Returns the default max timeout after which synchronous replication calls
     * return.
     * @return long Number of milliseconds after which a sync repl call must
     * return. 0 means to wait forever
     */
    long getSyncReplTimeout() {
        return sync_repl_timeout;
    }

    /** Sets the default maximum wait time for synchronous replication to receive all results */
    void setSyncReplTimeout(long timeout) {
        this.sync_repl_timeout=timeout;
    }

    /**
     * Default max time to wait for a lock. If the lock cannot be acquired
     * within this time, a LockingException will be thrown.
     * @return long Max number of milliseconds to wait for a lock to be acquired
     */
    long getLockAcquisitionTimeout() {
        return lock_acquisition_timeout;
    }


    /** Set the max time for lock acquisition. A value of 0 means to wait forever (not recomended).
     * Note that lock acquisition timeouts may be removed in the future when we
     * have deadlock detection.
     * @param timeout
     */
    void setLockAcquisitionTimeout(long timeout) {
        this.lock_acquisition_timeout=timeout;
    }


    /** Max time a lock can be held. After this time the lock is released.
     * (Not currently used.)
     * @return long The max number of milliseconds to hold a lock
     */
    long getLockLeaseTimeout() {
        return lock_lease_timeout;
    }

    /** Sets the max time a lock can be held */
    void setLockLeaseTimeout(long timeout) {
        this.lock_lease_timeout=timeout;
    }

    /**
     * Returns the commit.
     * @return boolean
     */
    public boolean isCommit() {
        return commit;
    }

    /**
     * Sets the commit.
     * @param commit The commit to set
     */
    public void setCommit(boolean commit) {
        this.commit=commit;
    }


    /**
     * @see java.lang.Object#toString()
     */
    public String toString() {
        StringBuffer sb=new StringBuffer();
        sb.append(modeToString(caching_mode));
        sb.append(", sync_repl_timeout=").append(sync_repl_timeout);
        sb.append(", lock_acquisition_timeout=").append(lock_acquisition_timeout);
        sb.append(", lock_lease_timeout=").append(lock_lease_timeout);
        sb.append(", commit=").append(commit);
        return sb.toString();
    }


    // TODO: add more eviction policy properties (e.g. eviction mode etc)

    public static String modeToString(int m) {
        switch(m) {
            case TRANSIENT:
                return "TRANSIENT";
            case REPL_ASYNC:
                return "REPL_ASYNC";
            case REPL_SYNC:
                return "REPL_SYNC";
            default :
                return "<unknown>";
        }
    }


}
