/*
 * 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.Cluster;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Loader;
import org.apache.catalina.SessionIdGenerator;
import org.apache.catalina.Valve;
import org.apache.catalina.ha.CatalinaCluster;
import org.apache.catalina.ha.ClusterManager;
import org.apache.catalina.ha.tcp.ReplicationValve;
import org.apache.catalina.session.ManagerBase;
import org.apache.catalina.tribes.io.ReplicationStream;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;

public abstract class ClusterManagerBase extends ManagerBase implements ClusterManager {

    private final Log log = LogFactory.getLog(ClusterManagerBase.class);

    /**
     * A reference to the cluster
     */
    protected CatalinaCluster cluster = null;

    /**
     * Should listeners be notified?
     */
    private boolean notifyListenersOnReplication = true;

    /**
     * cached replication valve cluster container!
     */
    private volatile ReplicationValve replicationValve = null ;

    /**
     * send all actions of session attributes.
     */
    private boolean recordAllActions = false;

    @Override
    public CatalinaCluster getCluster() {
        return cluster;
    }

    @Override
    public void setCluster(CatalinaCluster cluster) {
        this.cluster = cluster;
    }

    @Override
    public boolean isNotifyListenersOnReplication() {
        return notifyListenersOnReplication;
    }

    public void setNotifyListenersOnReplication(boolean notifyListenersOnReplication) {
        this.notifyListenersOnReplication = notifyListenersOnReplication;
    }

    /**
     * Return the string pattern used for including session attributes
     * to replication.
     *
     * @return the sessionAttributeFilter
     *
     * @deprecated Use {@link #getSessionAttributeNameFilter()}. Will be removed
     *             in Tomcat 8.5.x
     */
    @Deprecated
    public String getSessionAttributeFilter() {
        return getSessionAttributeNameFilter();
    }

    /**
     * Set the pattern used for including session attributes to replication.
     * If not set, all session attributes will be eligible for replication.
     * <p>
     * E.g. <code>^(userName|sessionHistory)$</code>
     * </p>
     *
     * @param sessionAttributeFilter
     *            the filter name pattern to set
     *
     * @deprecated Use {@link #setSessionAttributeNameFilter(String)}. Will be
     *             removed in Tomcat 8.5.x
     */
    @Deprecated
    public void setSessionAttributeFilter(String sessionAttributeFilter) {
        setSessionAttributeNameFilter(sessionAttributeFilter);
    }

    public boolean isRecordAllActions() {
        return recordAllActions;
    }

    public void setRecordAllActions(boolean recordAllActions) {
        this.recordAllActions = recordAllActions;
    }

    /**
     * Check whether the given session attribute should be distributed based on
     * attribute name only.
     *
     * @return true if the attribute should be distributed
     *
     * @deprecated Use {@link #willAttributeDistribute(String, Object)}. Will be
     *             removed in Tomcat 8.5.x
     */
    @Deprecated
    public boolean willAttributeDistribute(String name) {
        return willAttributeDistribute(name, null);
    }


    public static ClassLoader[] getClassLoaders(Context context) {
        ClassLoader tccl = Thread.currentThread().getContextClassLoader();
        Loader loader = context.getLoader();
        ClassLoader classLoader = null;
        if (loader != null) {
            classLoader = loader.getClassLoader();
        }
        if (classLoader == null) {
            classLoader = tccl;
        }
        if (classLoader == tccl) {
            return new ClassLoader[] {classLoader};
        } else {
            return new ClassLoader[] {classLoader, tccl};
        }
    }


    public ClassLoader[] getClassLoaders() {
        return getClassLoaders(getContext());
    }

    @Override
    public ReplicationStream getReplicationStream(byte[] data) throws IOException {
        return getReplicationStream(data,0,data.length);
    }

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


    //  ---------------------------------------------------- persistence handler

    /**
     * {@link org.apache.catalina.Manager} implementations that also implement
     * {@link ClusterManager} do not support local session persistence.
     */
    @Override
    public void load() {
        // NOOP
    }

    /**
     * {@link org.apache.catalina.Manager} implementations that also implement
     * {@link ClusterManager} do not support local session persistence.
     */
    @Override
    public void unload() {
        // NOOP
    }

    protected void clone(ClusterManagerBase copy) {
        copy.setName("Clone-from-" + getName());
        copy.setMaxActiveSessions(getMaxActiveSessions());
        copy.setProcessExpiresFrequency(getProcessExpiresFrequency());
        copy.setNotifyListenersOnReplication(isNotifyListenersOnReplication());
        copy.setSessionAttributeNameFilter(getSessionAttributeNameFilter());
        copy.setSessionAttributeValueClassNameFilter(getSessionAttributeValueClassNameFilter());
        copy.setWarnOnSessionAttributeFilterFailure(getWarnOnSessionAttributeFilterFailure());
        copy.setSecureRandomClass(getSecureRandomClass());
        copy.setSecureRandomProvider(getSecureRandomProvider());
        copy.setSecureRandomAlgorithm(getSecureRandomAlgorithm());
        if (getSessionIdGenerator() != null) {
            try {
                SessionIdGenerator copyIdGenerator = sessionIdGeneratorClass.newInstance();
                copyIdGenerator.setSessionIdLength(getSessionIdGenerator().getSessionIdLength());
                copyIdGenerator.setJvmRoute(getSessionIdGenerator().getJvmRoute());
                copy.setSessionIdGenerator(copyIdGenerator);
            } catch (InstantiationException | IllegalAccessException e) {
             // Ignore
            }
        }
        copy.setRecordAllActions(isRecordAllActions());
    }

    /**
     * Register cross context session at replication valve thread local
     * @param session cross context session
     */
    protected void registerSessionAtReplicationValve(DeltaSession session) {
        if(replicationValve == null) {
            CatalinaCluster cluster = getCluster() ;
            if(cluster != null) {
                Valve[] valves = cluster.getValves();
                if(valves != null && valves.length > 0) {
                    for(int i=0; replicationValve == null && i < valves.length ; i++ ){
                        if(valves[i] instanceof ReplicationValve) replicationValve =
                                (ReplicationValve)valves[i] ;
                    }//for

                    if(replicationValve == null && log.isDebugEnabled()) {
                        log.debug("no ReplicationValve found for CrossContext Support");
                    }//endif
                }//end if
            }//endif
        }//end if
        if(replicationValve != null) {
            replicationValve.registerReplicationSession(session);
        }
    }

    @Override
    protected void startInternal() throws LifecycleException {
        super.startInternal();
        if (getCluster() == null) {
            Cluster cluster = getContext().getCluster();
            if (cluster instanceof CatalinaCluster) {
                setCluster((CatalinaCluster)cluster);
            }
        }
        if (cluster != null) cluster.registerManager(this);
    }

    @Override
    protected void stopInternal() throws LifecycleException {
        if (cluster != null) cluster.removeManager(this);
        replicationValve = null;
        super.stopInternal();
    }
}
