#ifndef LIP_OPCUA_SC_H
#define LIP_OPCUA_SC_H

#include "lip/app/opcua/types/lip_opcua_base_types.h"
#include "lip/app/opcua/types/lip_opcua_tstmp.h"
#include "lip/app/opcua/types/lip_opcua_string.h"
#include "lip/app/opcua/lip_opcua_svc_proto_defs.h"
#include "ltimer.h"


struct st_lip_opcua_session_ctx;
struct st_lip_opcua_sc_ctx;

typedef struct {
    uint32_t SecureChannelId;
    uint32_t TokenId;
    t_lip_opcua_datetime CreatedAt;
    uint32_t RevisedLifetime;
    t_ltimer ExpireTimer; /* таймер для отслеживания истечения времени жизни токена */
} t_lip_opcua_sc_token;



typedef struct {
    uint32_t SecureChannelId;
    uint32_t TockenId;
    uint32_t SequenceNumber;
    uint32_t RequestId;
} t_lip_opcua_sc_msg_info;



typedef struct {
    t_lip_opcua_string_ptr ClientCertificate;
    t_lip_opcua_string_ptr ClientCertificateThumbprint;
    t_lip_opcua_sectoken_reqtype requestType;
    uint32_t SecureChannelId;
    t_lip_opcua_msg_secmode securityMode;
    t_lip_opcua_string_ptr SecurityPolicyUri;
    t_lip_opcua_string_ptr ClientNonce;
    uint32_t requestedLifetime;
} t_lip_opcua_sc_open_params;


void lip_opcua_scs_init(void);
void lip_opcua_scs_close(void);
void lip_opcua_scs_pull(void);

t_lip_opcua_err lip_opcua_sc_create(const t_lip_opcua_sc_open_params *params, t_lip_opcua_datetime dt, uint32_t seqnum, struct st_lip_opcua_sc_ctx **new_sc, t_lip_opcua_sc_token **token, t_lip_opcua_string_ptr *server_nonce);
t_lip_opcua_err lip_opcua_sc_renew_token(struct st_lip_opcua_sc_ctx *sc, const t_lip_opcua_sc_open_params *params, t_lip_opcua_sc_token **token, t_lip_opcua_string_ptr *server_nonce);
void lip_opcua_sc_close(struct st_lip_opcua_sc_ctx *sc);
void lip_opcua_sc_set_session(struct st_lip_opcua_sc_ctx *sc, struct st_lip_opcua_session_ctx *session);
struct st_lip_opcua_session_ctx *lip_opcua_sc_session(struct st_lip_opcua_sc_ctx *sc);

t_lip_opcua_err lip_opcua_sc_check_rx_seqnum(struct st_lip_opcua_sc_ctx *sc, uint32_t sc_id, uint32_t seqnum);
void lip_opcua_next_rx_seqnum(struct st_lip_opcua_sc_ctx *sc);
t_lip_opcua_err lip_opcua_sc_check_msg_params(struct st_lip_opcua_sc_ctx *sc, const t_lip_opcua_sc_msg_info *msg);
void lip_opcua_sc_next_msg(struct st_lip_opcua_sc_ctx *sc);

#endif // LIP_OPCUA_SC_H
