#ifndef LIP_OPCUA_SERVER_SESSION_H
#define LIP_OPCUA_SERVER_SESSION_H

#include "lip/app/opcua/types/lip_opcua_types.h"
#include "lip/app/opcua/types/lip_opcua_nodeid.h"
#include "lip/app/opcua/server/lip_opcua_server.h"
#include "lip/app/opcua/server/monitems/lip_opcua_server_subscriptions.h"
#include "lip/app/opcua/server/req/lip_opcua_server_req.h"
#include "lip_opcua_server_cfg_defs.h"

struct st_lip_opcua_session_ctx;
struct st_lip_opcua_srvsub_ctx;




typedef struct {
    struct st_lip_opcua_sc_ctx *sc;
    t_lip_opcua_string_ptr epUrl;
    t_lip_opcua_string_ptr sessionName;
    t_lip_opcua_string_ptr nonce;
    uint32_t sessionTout;
    uint32_t maxRespSize;
} t_lip_opcua_session_create_params;

typedef struct {
    t_lip_opcua_nodeid session_id;
    t_lip_opcua_nodeid token_id;
    uint32_t sessionTout;
    uint32_t maxReqSize;
} t_lip_opcua_session_create_result;

typedef struct {
    struct st_lip_opcua_sc_ctx *sc;
    t_lip_opcua_string_ptr_array localeIds;
    t_lip_opcua_signature_data clientSign;
    t_lip_opcua_user_token userToken;
    t_lip_opcua_signature_data userTokenSign;
} t_lip_opcua_session_activate_params;

void lip_opcua_sessions_init(void);
void lip_opcua_sessions_pull(void);
void lip_opcua_sessions_close(void);

void lip_opcua_session_clear_sc(struct st_lip_opcua_session_ctx *session);

t_lip_opcua_err lip_opcua_check_user_auth_token(struct st_lip_opcua_session_ctx *session, const t_lip_opcua_nodeid *token_node_id);

t_lip_opcua_err lip_opcua_session_create(const t_lip_opcua_session_create_params *params, t_lip_opcua_session_create_result *result);
t_lip_opcua_err lip_opcua_session_activate(struct st_lip_opcua_session_ctx *session, const t_lip_opcua_session_activate_params *params, t_lip_opcua_string_ptr *nonce);
t_lip_opcua_err lip_opcua_session_close(struct st_lip_opcua_session_ctx *session, bool deleteSubs);

#if LIP_OPCUA_SERVER_SUBS_ENABLE
t_lip_opcua_err lip_opcua_session_sub_create(struct st_lip_opcua_session_ctx *session, t_lip_opcua_subscription_params *params, bool publish_en, t_lip_opcua_intid *subid);
t_lip_opcua_err lip_opcua_session_sub_delete(struct st_lip_opcua_session_ctx *session, t_lip_opcua_intid subid);
t_lip_opcua_err lip_opcua_session_sub_get(struct st_lip_opcua_session_ctx *session, t_lip_opcua_intid subid, struct st_lip_opcua_srvsub_ctx **sub);
t_lip_opcua_err lip_opcua_session_publish(struct st_lip_opcua_session_ctx *session, const t_lip_opcua_req_resp_info *req_info);

bool lip_opcua_session_has_publish_req(struct st_lip_opcua_session_ctx *session);
t_lip_proc_buf *lip_opcua_server_session_publish_resp_prepare(struct st_lip_opcua_session_ctx *session, t_lip_opcua_intid subid, t_lip_proc_buf *more_notify_buf);
t_lip_opcua_err lip_opcua_server_session_publish_resp_finish(struct st_lip_opcua_session_ctx *session, t_lip_proc_buf *buf);
#endif


#endif // LIP_OPCUA_SERVER_SESSION_H

