/*-------------------------------------------------------------------------
 *
 * replicate.h
 *	  Primary include file for replicate server .c files
 *
 * This should be the first file included by replicate modules.
 *
 *-------------------------------------------------------------------------
 */
#ifndef REPLICATE_H
#define	REPLICATE_H

#ifndef _SYS_TIME_H
#include <sys/time.h>
#endif
#include "tcop/dest.h"
#include "storage/proc.h"
#include "replicate_com.h"

#define STAND_ALONE_TAG "When_Stand_Alone"
#define NOT_REPLICATE_INFO_TAG "Not_Replicate_Info"
#define DB_NAME_TAG	"DB_Name"
#define TABLE_NAME_TAG "Table_Name"

#define CLUSTER_CONF_FILE	"cluster.conf"
#define	NOT_SESSION_AUTHORIZATION	(0)
#define SESSION_AUTHORIZATION_BEGIN	(1)
#define SESSION_AUTHORIZATION_END	(2)

#define READ_ONLY_IF_STAND_ALONE	"read_only"
#define READ_WRITE_IF_STAND_ALONE	"read_write"
#define PERMIT_READ_ONLY		(1)
#define PERMIT_READ_WRITE		(2)
#define STATUS_REPLICATED		(3)
#define STATUS_CONTINUE			(4)
#define STATUS_CONTINUE_SELECT	(5)
#define STATUS_NOT_REPLICATE	(6)
#define STATUS_SKIP_QUERY		(7)
#define STATUS_REPLICATE		(10)
#define STATUS_RECOVERY			(11)
#define STATUS_REPLICATION_ABORT	(98)
#define STATUS_DEADLOCK_DETECT	(99)

#define TO_REPLICATION_SERVER	(0)
#define TO_FRONTEND				(1)

#define PGR_DEADLOCK_DETECTION_MSG "deadlock detected!"
#define PGR_REPLICATION_ABORT_MSG "replication aborted!"
#define SKIP_QUERY_1 "begin; select getdatabaseencoding(); commit"
#define SKIP_QUERY_2 "BEGIN; SELECT usesuper FROM pg_catalog.pg_user WHERE usename = '%s'; COMMIT"
#define SKIP_QUERY_3 "SET autocommit TO 'on'"
#define SKIP_QUERY_4 "SET search_path = public"

#define PGR_SEND_RETRY_CNT (3)
#define PGR_SEND_WAIT_MSEC (150)
#define PGR_RECV_RETRY_CNT (3)
#define PGR_RECV_WAIT_MSEC (150)
#define PGR_SEND_TIMEOUT	(5)
#define PGR_RECV_TIMEOUT	(5)
#define PGR_LOCK_RETRY_CNT (50)
#define PGR_LOCK_WAIT_MSEC (20)

#define PGR_1ST_RECOVERY (1)
#define PGR_2ND_RECOVERY (2)

typedef struct
{
	bool is_stand_alone;
	int  permit;
} PGR_Stand_Alone_Type;

typedef struct
{
	char db_name[DBNAME_MAX_LENGTH];
	char table_name[TABLENAME_MAX_LENGTH];
} PGR_Not_Replicate_Type;

typedef struct
{
	bool check_lock_conflict;
	bool deadlock;
	int status_lock_conflict;
	int dest;
} PGR_Check_Lock_Type;

typedef struct
{
	char * query_string;
	int query_len;
	char cmdSts;
	char cmdType;
	char useFlag;
} PGR_Retry_Query_Type;


/* replicaition log */
typedef struct {
	uint32_t PGR_Replicate_ID;
	uint32_t PGR_Request_ID;
} PGR_ReplicationLog_Info;


extern char * Query_String;
extern int TransactionQuery;
extern bool Transaction_Mode;
extern bool Session_Authorization_Mode;
extern bool Create_Temp_Table_Mode;
extern int RecoveryPortNumber;
extern char * RsyncPath;
extern char * RsyncOption;
extern bool RsyncCompress;
extern int TransactionSock;
extern ReplicateNow * ReplicateCurrentTime;
extern CopyData * PGRCopyData;
extern bool PGR_Copy_Data_Need_Replicate;
extern PGR_Stand_Alone_Type * PGR_Stand_Alone;
extern PGR_Not_Replicate_Type * PGR_Not_Replicate;
extern int PGR_Not_Replicate_Rec_Num;
extern bool autocommit;
extern bool PGR_Is_Replicated_Query;
extern PGR_Check_Lock_Type PGR_Check_Lock;
extern int PGR_Sock_To_Replication_Server;
extern bool PGR_Need_Notice;
extern bool PGR_Lock_Noticed;
extern ReplicateServerInfo * CurrentReplicateServer;
extern ReplicateServerInfo * LastReplicateServer;
extern char * PGRSelfHostName;
extern int PGR_Pending_Sem_Num;
extern int PGR_Response_Mode;
extern bool PGR_Reliable_Mode_Wait;
extern PGR_Retry_Query_Type PGR_Retry_Query;
extern bool PGRforceLoadBalance;
extern bool needToUpdateReplicateIdOnNextQueryIsDone;
extern PGR_ReplicationLog_Info ReplicationLog_Info;
extern bool PGR_Not_Replication_Query;

/* in backend/libpq/replicate.c */
extern int PGR_Init_Replicate_Server_Data(void);
extern int PGR_Set_Replicate_Server_Socket(void);
extern ReplicateServerInfo * PGR_get_replicate_server_info(void);
extern char * PGR_Send_Replicate_Command(char * query_string, int query_len, char cmdSts ,char cmdType);
extern bool PGR_Is_Replicated_Command(char * query);
extern int Xlog_Check_Replicate(int operation);
extern int PGR_Replicate_Function_Call(void);
extern void PGR_delete_shm(void);
extern int PGR_replication(char * query_string, CommandDest dest, Node *parsetree, const char * commandTag);
extern bool PGR_Is_System_Command(char * query);
extern int PGR_Call_System_Command(char * command);
extern int PGR_GetTimeOfDay(struct timeval *tp,struct timezone *tpz);
extern long PGR_Random(void);
extern int PGR_Set_Current_Time(char * sec, char * usec);
extern int PGR_Send_Copy(CopyData * copy, int end);
extern CopyData * PGR_Set_Copy_Data(CopyData * copy, char *str, int len, int end);
extern char * PGR_scan_terminate( char * str);
extern bool PGR_Is_Stand_Alone(void);
extern void PGR_Send_Message_To_Frontend(char * msg);
extern void PGR_Notice_Transaction_Query_Done(void);
extern void PGR_Notice_Transaction_Query_Aborted(void);
extern int PGR_Notice_Conflict(void);
extern int PGR_Recv_Trigger (int user_timeout);
extern bool PGR_Check_DeadLock(LOCKMETHODTABLE *lockMethodTable, LOCKMODE lockmode, LOCK *lock, PROCLOCK *holder);
extern void PGR_Set_Replication_Server_Status( ReplicateServerInfo * sp, int status);
extern int PGR_Is_Skip_Replication(char * query);
extern bool PGR_Did_Commit_Transaction(void);
extern bool PGR_Set_Transaction_Mode(bool mode,const char * commandTag);
extern char * PGR_Remove_Comment(char * str);
extern void PGR_Force_Replicate_Query(void);
extern void PGR_Notice_DeadLock(void);
extern void PGR_Set_Cluster_Status(int status);
extern int PGR_Get_Cluster_Status(void);
extern int PGR_Check_Replicate_Server_Status(ReplicateServerInfo * sp);

/* in backend/libpq/recovery.c */
extern int PGR_Master_Main(void);
extern int PGR_Recovery_Main(void);
extern int PGR_recovery_error_send(void);
extern int PGR_recovery_finish_send(void);

/* in backend/access/transam/xact.c */
extern void PGR_Reload_Start_Time(void);
#endif /* REPLICATE_H */
