/*
 * $Source: /opt/cvsroot/erserver/src/com/postgres/replic/server/AbstractReplicationRunnable.java,v $
 * $Author: ronz $ $Revision: 1.2 $ $Date: 2003/12/03 12:48:01 $
 *
 */

package com.postgres.replic.server;

import com.postgres.replic.server.props.ConnectionPoolProps;
import com.postgres.replic.server.props.ServerProps;
import com.postgres.replic.util.Rserv;
import com.postgres.util.Logger.LogRepl;
import com.postgres.util.Logger.Logger;
import com.postgres.util.jdbc.ConnectionPool;

import java.sql.Connection;

public abstract class AbstractReplicationRunnable extends Thread {
	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 void resetDBProcessors() {
		rServ.resetDBProcessors();
	}

	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) {
			e.printStackTrace();
			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) {
		}
	}
}
