
#ifndef ETHERCAT_MASTER_DIAGNOSTICS_H
#define ETHERCAT_MASTER_DIAGNOSTICS_H

#include "../ethercat_types.h"
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

#ifndef EC_DIAGNOSTICS_SNAPSHOT_DEFINED
#define EC_DIAGNOSTICS_SNAPSHOT_DEFINED

typedef struct {
    int         frequency;
    uint32_t    error_count;
    float       packet_loss_rate;
    float       late_frame_rate;

    double      mailbox_latency_avg_us;
    double      mailbox_latency_us;
    int         cycle_time_us;
    uint16_t    wkc_actual;
    uint16_t    wkc_expected;
    uint32_t    bus_cycle_hz;
    double      bus_max_jitter_us;
    double      bus_avg_jitter_us;
    double      bus_roundtrip_us;
    double      bus_load_percent;
    uint32_t    smi_count;
    double      smi_peak_us;
    int         primary_port_ok;
    int         secondary_port_ok;
    int         redundancy_active;
} ec_diagnostics_snapshot_t;
#endif

#ifndef DYNAMIC_LOAD

void*    GetMasterState(uint16_t master_index);

void*    GetMasterStateCache(uint16_t master_index);

void*    GetSlave(uint16_t master_index, uint16_t slave_index);
void*    GetSlaveDetailedInfo(uint16_t master_index, uint16_t slave_index);

void*    GetCommunicationStats(uint16_t master_index);
void     ResetCommunicationStats(uint16_t master_index);

void*    GetDetailedDiagnostics(uint16_t master_index);
void     ResetDiagnostics(uint16_t master_index);
const void* GetDiagnosticsPointer(uint16_t master_index);
const void* GetSummaryPointer(uint16_t master_index);
void     SetDiagnosticsEnabled(uint16_t master_index, BOOL enable);
BOOL     GetDiagnosticsEnabled(uint16_t master_index);

uint16_t GetExpectedWKC(uint16_t master_index);

float GetPacketLossRate(uint16_t master_index);
float GetLateFrameRate(uint16_t master_index);
uint32_t GetWdkPrimaryFrameTx(uint16_t master_index);
uint32_t GetWdkPrimaryFrameRx(uint16_t master_index);
uint32_t GetWdkSecondaryFrameTx(uint16_t master_index);
uint32_t GetWdkSecondaryFrameRx(uint16_t master_index);
uint32_t GetWdkPdoIdxDropCount(uint16_t master_index);
void     SetExpectedWKC(uint16_t master_index, uint16_t expected_wkc);
int16_t  GetSlaveLinkQuality(uint16_t master_index, uint16_t slave_index);

void     RecordPDOCycleStart(uint16_t master_index);
void     RecordWKC(uint16_t master_index, uint16_t wkc);
void     UpdateDiagnosticsSnapshot(uint16_t master_index);
BOOL     ResetSlavePortErrorCounters(uint16_t master_index, uint16_t slave_index);

void     DumpSlaveStructOffsets(void);

BOOL     GetMasterIdentity(uint16_t master_index, ec_master_identity_t* identity);

BOOL     GetMasterDiagData(uint16_t master_index, ec_master_diag_data_t* diag);

int      ec_validate_config(uint16_t master_index);

int      ec_perf_export_csv(uint16_t master_index, const char* filepath);

int      GetBreakPoints(uint16_t master_index,
                         uint16_t* out_slaves, uint8_t* out_ports,
                         uint8_t* out_types, uint16_t max_results);

int      GetRingMode(uint16_t master_index);

BOOL     GetSecondaryLinkStatus(uint16_t master_index);

uint16_t GetPrimaryWKC(void);
uint16_t GetSecondaryWKC(void);

BOOL     ReadSlavePortErrorCounters(uint16_t master_index, uint16_t slave_index,
                                     uint8_t* rx_error, uint8_t* invalid_frame,
                                     uint8_t* lost_link);
int      ReadAllSlavePortErrorCounters(uint16_t master_index);

void*    GetSlavePortErrorStats(uint16_t master_index, uint16_t slave_index);
void     UpdateDiagnosticsWithESCErrors(uint16_t master_index);

BOOL GetDiagnosticsSnapshot(uint16_t master_index, ec_diagnostics_snapshot_t* snapshot);

uint8_t  GetSlaveWcState(uint16_t master_index, uint16_t slave_index);

uint16_t GetSlaveAlStatusMirror(uint16_t master_index, uint16_t slave_index);

uint16_t GetWcDeficit(uint16_t master_index);

uint64_t GetWcStateSeq(uint16_t master_index);

uint16_t GetMappedSlaveCount(uint16_t master_index);

uint16_t GetWkcActualMirror(uint16_t master_index);

uint16_t GetWkcExpectedMirror(uint16_t master_index);

uint8_t  GetSlaveFreeRunDemoted(uint16_t master_index, uint16_t slave_index);

uint8_t  GetSlaveMailboxHealth(uint16_t master_index, uint16_t slave_index);

uint32_t GetSlaveHealthDegradedCount(uint16_t master_index, uint16_t slave_index);

BOOL     RecoverSlaveMailboxHealth(uint16_t master_index, uint16_t slave_index);

int      HotSwapRebuild(uint16_t master_index);

#endif

#ifdef __cplusplus
}
#endif

#endif
