// ensemble imports
#include "hot_sys.h"
#include "hot_error.h"
#include "hot_msg.h"
#include "hot_ens.h"
#include "hot_thread.h"



// simulation package import
//#include <csim.h>

// common declarations
#include "declarations.h"
#include "qmsockets.h"
#include "mc_send.h"
#include "socku.h"
#include "utilities.h"

// pgserver
#include "pgserver.h"

// semaphore
#include "semaphore.h"

// threads
#include "threads.h"


// dcadena
#ifndef GROUPCOMM
#define GROUPCOMM

// dcadena. Inside context_state
//hot_view_state_t view;
//int my_rank[2];         // member id on each group

char my_name[100 /*+ EXTRASIZE - RMEXTRASIZE*/];      // member endpoint

// boolean consts
#define false 0;
#define true 1;

// semaphore to block the main program
semaphore block_main_sem;

// mutex for concurrent deliveries (opt and to)
semaphore mutex_deli;

int INITIAL_MEMBERS; // initial number of replicas
int REAL_MEMBERS;   // real number of replicas
int MY_ID;    // replica identifier
// 280803
//int NUM_TOTAL_CC=-1; //number of conflict classes
//int NUM_LOCAL_CC=-1; // number of conflict classes of this replica

int hb_rate;

// number of trans to_delivered
//int opts_received, tos_received;
static ncasts;        // number of multicasts received

// 030903
int numConnection;  // the last id connection
semaphore nconn_mutex;

// dcadena. Inside context_state
//int complete[2];        // [i]==true when the membership of group i is complete
//int my_rank[2];         // member id on each group

//typedef long msg_array[(N_TXN+2*WARMUP)*100];
//typedef msg_array order_array[2];
//order_array order;      // array to measure the disordering
//order_array arrival_s;  // array with arrival times
//order_array arrival_us; // array with arrival times
//order_array disorder;   // array to measure the disordering
//long idx[2];    // idx to the next message to insert
hot_uint32 seqno;     // next message id to send

int sender;             // true if sender_thread started
char *query_res;        // transaction result (protected by the above sem)


enum kind_of_multicast {TOTAL, FIFO};

// state associated to group contexts
typedef struct {
  int magic ;
  hot_gctx_t gctx;                  // group context
  hot_view_state_t vs;              // current view
  hot_ens_JoinOps_t jops;           // parameters
  enum kind_of_multicast mcast_kind;// kind of group
  // dcadena
  int complete;                     // true when the membership of group i is complete
} context_state ;

// hot_gctx_t contexts[2];
context_state contexts[2]; //contexts for the total[0] and fifo[1] groups

bool begin;

// JM Milan (02-12-03)
// Defined to avoid race conditions when getting/releasing free QM
semaphore QM_mutex;

//int last_update_petition[MAXCLIENTS];

void MulticastCommit(char*, hot_uint32, char*, hot_uint32, hot_uint32, hot_uint32, hot_uint32);

  // writeset, writeset_length, tid
void SendReply(hot_endpt_t, char*);
  // destination, result message
void SendUnicastToThread (char *, hot_uint32, hot_uint32, hot_endpt_t, hot_uint32);

void MulticastOptTo(char*, hot_uint32, hot_uint32 *, hot_uint32, char, hot_uint32, hot_uint32, hot_uint32, char *);
char *SendQuery(char *, hot_uint32, hot_uint32 *,  hot_uint32, char, hot_uint32, hot_uint32, char *);
void SendQueryUnicast(char*, hot_uint32, hot_uint32 *, hot_uint32, hot_uint32, hot_uint32, char *);

void sendMsgInit ();
void sendMsgConnection (char *, hot_uint32, hot_uint32);

//int getRank (

#endif
