/*
 * 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.catalina.ha.session;

import java.io.ByteArrayInputStream;
import java.io.IOException;

import org.apache.catalina.LifecycleException;
import org.apache.catalina.Loader;
import org.apache.catalina.Session;
import org.apache.catalina.ha.CatalinaCluster;
import org.apache.catalina.ha.ClusterManager;
import org.apache.catalina.ha.ClusterMessage;
import org.apache.catalina.session.StandardManager;
import org.apache.catalina.tribes.Member;
import org.apache.catalina.tribes.io.ReplicationStream;
import org.apache.catalina.tribes.tipis.LazyReplicatedMap;
import org.apache.catalina.tribes.Channel;

/**
 *@author Filip Hanik
 *@version 1.0
 */
public class BackupManager extends StandardManager implements ClusterManager
{
    public static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog( BackupManager.class );

    protected static long DEFAULT_REPL_TIMEOUT = 15000;//15 seconds

    /** Set to true if we don't want the sessions to expire on shutdown */
    protected boolean mExpireSessionsOnShutdown = true;
    
    /**
     * The name of this manager
     */
    protected String name;

    /**
     * A reference to the cluster
     */
    protected CatalinaCluster cluster;
    
    /**
     * Should listeners be notified?
     */
    private boolean notifyListenersOnReplication;
    /**
     * 
     */
    private int mapSendOptions = Channel.SEND_OPTIONS_SYNCHRONIZED_ACK|Channel.SEND_OPTIONS_USE_ACK;

    /**
     * Constructor, just calls super()
     *
     */
    public BackupManager() {
        super();
    }


//******************************************************************************/
//      ClusterManager Interface     
//******************************************************************************/

    public void messageDataReceived(ClusterMessage msg) {
    }

    public boolean isSendClusterDomainOnly() {
        return false;
    }

    /**
     * @param sendClusterDomainOnly The sendClusterDomainOnly to set.
     */
    public void setSendClusterDomainOnly(boolean sendClusterDomainOnly) {
    }

    /**
     * @return Returns the defaultMode.
     */
    public boolean isDefaultMode() {
        return false;
    }
    /**
     * @param defaultMode The defaultMode to set.
     */
    public void setDefaultMode(boolean defaultMode) {
    }

    public void setExpireSessionsOnShutdown(boolean expireSessionsOnShutdown)
    {
        mExpireSessionsOnShutdown = expireSessionsOnShutdown;
    }

    public void setCluster(CatalinaCluster cluster) {
        if(log.isDebugEnabled())
            log.debug("Cluster associated with SimpleTcpReplicationManager");
        this.cluster = cluster;
    }

    public boolean getExpireSessionsOnShutdown()
    {
        return mExpireSessionsOnShutdown;
    }


    /**
     * Override persistence since they don't go hand in hand with replication for now.
     */
    public void unload() throws IOException {
    }
    
    public ClusterMessage requestCompleted(String sessionId) {
        if ( !this.started ) return null;
        LazyReplicatedMap map = (LazyReplicatedMap)sessions;
        map.replicate(sessionId,false);
        return null;
    }


//=========================================================================
// OVERRIDE THESE METHODS TO IMPLEMENT THE REPLICATION
//=========================================================================

    public Session createEmptySession() {
        return new DeltaSession(this);
    }
    
    public ClassLoader[] getClassLoaders() {
        return ClusterManagerBase.getClassLoaders(this.container);
    }

    /**
     * Open Stream and use correct ClassLoader (Container) Switch
     * ThreadClassLoader
     * 
     * @param data
     * @return The object input stream
     * @throws IOException
     */
    public ReplicationStream getReplicationStream(byte[] data) throws IOException {
        return getReplicationStream(data,0,data.length);
    }

    public ReplicationStream getReplicationStream(byte[] data, int offset, int length) throws IOException {
        ByteArrayInputStream fis = new ByteArrayInputStream(data, offset, length);
        return new ReplicationStream(fis, getClassLoaders());
    }    




    public String getName() {
        return this.name;
    }
    /**
     * Prepare for the beginning of active use of the public methods of this
     * component.  This method should be called after <code>configure()</code>,
     * and before any of the public methods of the component are utilized.<BR>
     * Starts the cluster communication channel, this will connect with the other nodes
     * in the cluster, and request the current session state to be transferred to this node.
     * @exception IllegalStateException if this component has already been
     *  started
     * @exception LifecycleException if this component detects a fatal error
     *  that prevents this component from being used
     */
    public void start() throws LifecycleException {
        if ( this.started ) return;
        try {
            CatalinaCluster catclust = (CatalinaCluster)cluster;
            catclust.addManager(getName(), this);
            LazyReplicatedMap map = new LazyReplicatedMap(this,
                                                          catclust.getChannel(),
                                                          DEFAULT_REPL_TIMEOUT,
                                                          getMapName(),
                                                          getClassLoaders());
            map.setChannelSendOptions(mapSendOptions);
            this.sessions = map;
            super.start();
        }  catch ( Exception x ) {
            log.error("Unable to start BackupManager",x);
            throw new LifecycleException("Failed to start BackupManager",x);
        }
    }
    
    public String getMapName() {
        CatalinaCluster catclust = (CatalinaCluster)cluster;
        String name = catclust.getManagerName(getName(),this)+"-"+"";
        if ( log.isDebugEnabled() ) log.debug("Backup manager, Setting map name to:"+name);
        return name;
    }

    /**
     * Gracefully terminate the active use of the public methods of this
     * component.  This method should be the last one called on a given
     * instance of this component.<BR>
     * This will disconnect the cluster communication channel and stop the listener thread.
     * @exception IllegalStateException if this component has not been started
     * @exception LifecycleException if this component detects a fatal error
     *  that needs to be reported
     */
    public void stop() throws LifecycleException
    {
        
        LazyReplicatedMap map = (LazyReplicatedMap)sessions;
        if ( map!=null ) {
            map.breakdown();
        }
        if ( !this.started ) return;
        try {
        } catch ( Exception x ){
            log.error("Unable to stop BackupManager",x);
            throw new LifecycleException("Failed to stop BackupManager",x);
        } finally {
            super.stop();
        }
        cluster.removeManager(getName(),this);

    }

    public void setDistributable(boolean dist) {
        this.distributable = dist;
    }

    public boolean getDistributable() {
        return distributable;
    }

    public void setName(String name) {
        this.name = name;
    }
    public boolean isNotifyListenersOnReplication() {
        return notifyListenersOnReplication;
    }
    public void setNotifyListenersOnReplication(boolean notifyListenersOnReplication) {
        this.notifyListenersOnReplication = notifyListenersOnReplication;
    }

    public void setMapSendOptions(int mapSendOptions) {
        this.mapSendOptions = mapSendOptions;
    }

    /* 
     * @see org.apache.catalina.ha.ClusterManager#getCluster()
     */
    public CatalinaCluster getCluster() {
        return cluster;
    }

    public int getMapSendOptions() {
        return mapSendOptions;
    }

    public String[] getInvalidatedSessions() {
        return new String[0];
    }

}
