/*
 * $Source: /usr/local/cvsroot/erserver/erserver/java/src/com/postgres/replic/server/AbstractReplicationRunnable.java,v $
 * $Author: asullivan $ $Revision: 1.1.1.1 $ $Date: 2003/08/26 19:02:21 $
 *
 */

package com.postgres.replic.server;

import com.postgres.replic.server.props.*;
import com.postgres.util.Logger.*;
import com.postgres.replic.util.*;
import com.postgres.replic.util.struct.*;
import com.postgres.util.config.*;
import com.postgres.util.jdbc.*;
import java.sql.*;

public abstract class AbstractReplicationRunnable implements Runnable {
    public static final int T_NO = -1;
    public static final int T_NULL = 0;
    private boolean initialized = false;
    private boolean debug = false;
    private boolean verbose = false;

    private Connection masterConn;
    private ConnectionPool masterPool;
    private Connection slaveConn;
    private ConnectionPool slavePool;
    private Rserv rServ;
    private ConnectionPoolProps connPoolProps;
    private ServerProps serverProps;
    private int serverId = T_NO;

    // signals:
    public static final int STOP = 1;

    // signal var:
    private int signal = 0;

    public void setSignal(int signal) {
        this.signal = signal;
    }

    public int getSignal() {
        return signal;
    }


    public AbstractReplicationRunnable(ServerProps serverProps,
    ConnectionPoolProps connPoolProps,
    ConnectionPool masterPool,
    ConnectionPool slavePool)
    throws ReplicationException {
        if (masterPool == null || slavePool == null) {
            throw new ReplicationException("AbstractReplicationRunnable:: masterPool == null || slavePool == null");
        }
        this.masterPool = masterPool;
        this.slavePool = slavePool;
        this.connPoolProps = connPoolProps;
        this.serverProps = serverProps;
        getRserv();
    }

    abstract public void run();

    protected ConnectionPoolProps getConnPoolProps() {
        return connPoolProps;
    }

    protected ServerProps getServerProps() {
        return serverProps;
    }

    protected Rserv getRserv() throws ReplicationException {
        try {

            if (rServ == null) {
                rServ = new Rserv();
                getLogger().debug("AbstractReplicationRunnable::getRserv: rServ = new Rserv();");
            } else {
                getLogger().debug("AbstractReplicationRunnable::getRserv: rServ="+rServ);
            }
            getLogger().debug("AbstractReplicationRunnable::getRserv: before rServ.init: initialized?: " +
            rServ.initialized() + "; serverProps="+serverProps);
            String slaveConnectionURL = slavePool.getConnectionURL();
            serverId = connPoolProps.getServerId(slaveConnectionURL);

            if (masterConn == null) {
                getLogger().debug("AbstractReplicationRunnable::getRserv: getting connection for MASTER: " + masterPool.getConnectionURL());
                masterConn = masterPool.getConnection();
            } else {
                getLogger().debug("AbstractReplicationRunnable::getRserv: connection for MASTER != null: ");
            }
            if (slaveConn == null) {
                getLogger().debug("AbstractReplicationRunnable::getRserv: getting connection for SLAVE: " + slavePool.getConnectionURL());
                slaveConn = slavePool.getConnection();

            } else {
                getLogger().debug("AbstractReplicationRunnable::getRserv: connection for SLAVE != null: ");
            }

            rServ.init(masterConn, slaveConn, serverId, serverProps);
            rServ.setDebug(getDebug());
            rServ.setVerbose(getVerbose());

        } catch (Exception e) {
            throw new ReplicationException("AbstractReplicationRunnable::getRserv: " +
            e.toString());
        } finally {

        }
        return rServ;
    }


    public boolean initialized() {
        return initialized;
    }

    public int getServerId() {
        return serverId;
    }


    protected void setInitialized(boolean initialized) {
        this.initialized = initialized;
    }

    public void setDebug(boolean debug) {
        this.debug = debug;
        if (rServ != null) {
            rServ.setDebug(debug);
        }
    }

    public boolean getDebug() {
        return debug;
    }

    public void setVerbose(boolean verbose) {
        this.verbose = verbose;
    }

    public boolean getVerbose() {
        return verbose;
    }

    private void validate() throws ReplicationException {

    }

    protected Logger getLogger() {
         return LogRepl.getInstance();
    }

    public String getMasterURL() {
        return masterPool.getConnectionURL();
    }

    public String getSlaveURL() {
        return slavePool.getConnectionURL();
    }

    public void destroy() {
        try {
            if (slavePool != null) {
                slavePool.destroy();
                slavePool = null;
            }
        } catch (Exception e) {}
        try {
            if (masterPool != null) {
                masterPool.destroy();
                masterPool = null;
            }
        } catch (Exception e) {}
    }
}
