/*
 *  FBCClusterAdmin.h
 *  Client
 *
 *  Created by Peter Haff on Fri Dec 19 2003.
 *  Copyright (c) 2003 FrontBase, Inc. All rights reserved.
 *
 */

#ifndef FBCClusterAdmin__H
#define FBCClusterAdmin__H

#ifndef FBVersion
#define FBVersion 7
#elif FBVersion != 7
#error "The headers for FBCAccess version have been mixed"
#endif

#include "FBCPList.h"
//=====================
// Property List Syntax
//=====================

//------------
// Basic types
//------------
// Host = String
// Id = String
// UniqueId = String
// Number = String
// Text = String
// Date = String

//-------------
// Common types
//-------------
// Members = Member-list
// Member :: Host Id
// Messages = Message-list
// Message :: Host Id Text
// Version = Number
// int = "True" | "False"

//--------------
// Cluster descr (for communication server/client)
//--------------
// ClusterDescr :: [Majority] MemberNames
// MemberNames = MemberName-list
// MemberName = "id@host"
// Majority = Bool

//--------------
// Cluster kinds
//--------------
// FBCClusterKind :: ClusterKind Messages
// ClusterKind = Unreachable | Unknown | Stopped | Running
// Unreachable :: Kind
// Unknown     :: Kind
// Stopped     :: Kind UniqueId Version [Majority] Members
// Running     :: Kind UniqueId Version [Majority] Members

//----------------
// Active members
//----------------
// FBCActiveMembers :: [ActiveMembers] Messages
// ActiveMembers :: ReadOnly Members
// ReadOnly = Bool

//---------------
// Member status
//---------------
// FBCMemberStatus :: [MemberStatus] Messages
// MemberStatus :: Member ClusterKind [ActiveMembers]

//---------------
// Cluster status
//---------------
// FBCClusterStatus :: [ClusterStatus] Messages
// ClusterStatus = MemberStatus-list

//------------
// Cluster log
//------------
// FBCClusterLog = Activity-list
// Activity = Initiated | Participated | Connected | Disconnected
// Initiated    :: Kind Date Version Members [Failed]
// Participated :: Kind Date Version [Failed]
// Connected    :: Kind Date Member
// Disconnected :: Kind Date Member
// Failed = SQL (= String)

//===============
// Symbolic names
//===============

// Key names
#define CAActiveMembers "ActiveMembers"
#define CAClusterDescr  "ClusterDescr"
#define CAClusterKind   "ClusterKind"
#define CAClusterStatus "ClusterStatus"
#define CADbId          "DbId"
#define CAFalse         "False"
#define CAHostId        "HostId"
#define CAKind          "Kind"
#define CAMajority      "Majority"
#define CAMember        "Member"
#define CAMembers       "Members"
#define CAMemberNames   "MemberNames"
#define CAMemberStatus  "MemberStatus"
#define CAMessages      "Messages"
#define CANumber        "Number"
#define CAReadOnly      "ReadOnly"
#define CAText          "Text"
#define CATrue          "True"
#define CAVersion       "Version"
#define CAUniqueId      "UniqueId"

// Database states
#define CAUnreachable "Unreachable"
#define CAUnknown     "Unknown"
#define CAStarting    "Starting"
#define CAStopped     "Stopped"
#define CARunning     "Running"

// Message texts
#define CAConnectionFailed   "Connection failed"
#define CACreatingDatabase   "Creating new database"
#define CAHostNoGood         "Cannot obtain proper hostname to replace 'localhost'"
#define CAIsInCluster        "Database is already a cluster member"
#define CAIsNotAccessible    "Database is not accessible"
#define CAIsRunning          "Database is running"
#define CAMajorityAlreadySet "Majority is already set within this cluster"
#define CAMustBeStopped      "Database must be stopped to start rest of cluster"
#define CANoExec             "No FBExec for host"
#define CANotInCluster       "Database is not a cluster member"
#define CANotInThisCluster   "Database is not a member of this cluster"
#define CASessionFailed      "Create session failed"
#define CAStopFailed         "Stop database failed"
#define CAUnexpectedFormat   "Unexpected format: '%s'"
#define CAUniqueIdMismatch   "Database IDs do not match"
#define CAUnknownDatabase    "Database is unknown"
#define CAUnreachableHost    "Unreachable host"

// Miscellaneous
#define CASessionID          "** CLUSTER_ADMIN **"
#define CASystemUser         "_SYSTEM"
#define CAToolId             "CLUSTER_ADMIN"

//===================
// External Interface
//===================

// Main syntactic categories
typedef FBCPList* FBCActiveMembers;
typedef FBCPList* FBCClusterKind;
typedef FBCPList* FBCClusterStatus;
typedef FBCPList* FBCMemberStatus;

#ifdef __cplusplus
extern "C" {
#endif

FBCClusterKind   fbccaGetClusterKind   ( char* hostId, char* dbId, char* dbPW, char* sysPW );
FBCActiveMembers fbccaGetActiveMembers ( char* hostId, char* dbId, char* dbPW, char* sysPW );
FBCMemberStatus  fbccaGetMemberStatus  ( char* hostId, char* dbId, char* dbPW, char* sysPW );
FBCClusterStatus fbccaGetClusterStatus ( char* hostId, char* dbId, char* dbPW, char* sysPW );
FBCClusterStatus fbccaSetClusterDescr  ( char* hostId, char* dbId, char* dbPW, char* sysPW, char* execPW );

FBCMemberStatus  fbccaStartMember  ( char* hostId, char* dbId, char* options, char* dbPW, char* sysPW, char* execPW );
FBCClusterStatus fbccaStartCluster ( char* hostId, char* dbId, char* dbPW, char* sysPW, char* execPW );
FBCMemberStatus  fbccaStopMember   ( char* hostId, char* dbId, char* dbPW, char* sysPW );
FBCClusterStatus fbccaStopCluster  ( char* hostId, char* dbId, char* dbPW, char* sysPW );

FBCClusterStatus fbccaCreateMember         ( char* hostId, char* dbId, char* options, char* dbPW, char* sysPW, char* execPW );
FBCClusterStatus fbccaAddMember            ( char* hostId, char* dbId, char* newHostId, char* newDbId, char* options, char* dbPW, char* sysPW, char* execPW );
FBCClusterStatus fbccaRemoveMember         ( char* hostId, char* dbId, char* oldHostId, char* oldDbId, char* dbPW, char* sysPW, char* execPW );
FBCClusterStatus fbccaRemoveMemberIsolated ( char* hostId, char* dbId, char* oldHostId, char* oldDbId, char* dbPW, char* sysPW, char* execPW );

FBCMemberStatus fbccaSetMemberReadOnly  ( char* hostId, char* dbId, char* dbPW, char* sysPW, int status );
FBCMemberStatus fbccaSetMemberMajority  ( char* hostId, char* dbId, char* dbPW, char* sysPW, char* execPW, int status );

int fbccaBoolValue ( const FBCPList* plist );
int fbccaIsUnreachable ( const FBCClusterKind clusterKind );
int fbccaIsKnown       ( const FBCClusterKind clusterKind );

FBCPList* fbccaParseMemberNames ( const FBCPList* memberNames, char** errorMessage );

char* fbccaUnparseMessage ( const FBCPList* message );
char* fbccaUnparseMember  ( const FBCPList* member );
char* fbccaUnparseMembers ( const FBCPList* members );

void fbccaFreeMessage ( char* message );

#ifdef __cplusplus
}
#endif

#endif /* FBCClusterAdmin__H  */
