#include "lip_opcua_server_cfg_defs.h"
#if LIP_OPCUA_SERVER_ENABLE
#include "lip_opcua_sc_msgproc.h"
#include "lip_opcua_sc_private.h"

t_lip_opcua_err lip_opcua_open_hdr_parse(t_lip_proc_buf *buf, t_lip_opcua_sc_seq_hdr *sc_hdr, t_lip_opcua_sc_open_params *params) {
    t_lip_opcua_err err = lip_opcua_procbuf_get_uint32(buf,  &params->SecureChannelId);
    if (err == LIP_OPCUA_ERR_GOOD) {
        err = lip_opcua_procbuf_get_string(buf, &params->SecurityPolicyUri);
    }
    if (err == LIP_OPCUA_ERR_GOOD) {
        err = lip_opcua_procbuf_get_string(buf, &params->ClientCertificate);
    }
    if (err == LIP_OPCUA_ERR_GOOD) {
        err = lip_opcua_procbuf_get_string(buf, &params->ClientCertificateThumbprint);
    }
    if (err == LIP_OPCUA_ERR_GOOD) {
        err = lip_opcua_procbuf_get_uint32(buf, &sc_hdr->SequenceNumber);
    }
    if (err == LIP_OPCUA_ERR_GOOD) {
        err = lip_opcua_procbuf_get_uint32(buf, &sc_hdr->RequestId);
    }
    return err;
}


t_lip_opcua_err lip_opcua_open_hdr_put(t_lip_proc_buf *buf, const t_lip_opcua_sc_seq_hdr *sc_hdr, const t_lip_opcua_sc_open_params *params, const t_lip_opcua_sc_token *token) {
    t_lip_opcua_err err = lip_opcua_procbuf_put_uint32(buf,  token->SecureChannelId);
    if (err == LIP_OPCUA_ERR_GOOD) {
        err = lip_opcua_procbuf_put_string(buf, &params->SecurityPolicyUri);
    }
    if (err == LIP_OPCUA_ERR_GOOD) {
        err = lip_opcua_procbuf_put_string(buf, &params->ClientCertificate);
    }
    if (err == LIP_OPCUA_ERR_GOOD) {
        err = lip_opcua_procbuf_put_string(buf, &params->ClientCertificateThumbprint);
    }
    if (err == LIP_OPCUA_ERR_GOOD) {
        err = lip_opcua_procbuf_put_uint32(buf, sc_hdr->SequenceNumber);
    }
    if (err == LIP_OPCUA_ERR_GOOD) {
        err = lip_opcua_procbuf_put_uint32(buf, sc_hdr->RequestId);
    }
    return err;
}

t_lip_opcua_err lip_opcua_sc_open_req_parse(t_lip_proc_buf *buf, t_lip_opcua_sc_open_params *params, uint32_t *proto_ver) {
    t_lip_opcua_err err = lip_opcua_procbuf_get_uint32(buf, proto_ver);
    if (err == LIP_OPCUA_ERR_GOOD) {
        uint32_t token_type;
        err = lip_opcua_procbuf_get_uint32(buf, &token_type);
        if (err == LIP_OPCUA_ERR_GOOD) {
            params->requestType = token_type;
        }
    }
    if (err == LIP_OPCUA_ERR_GOOD) {
        uint32_t sec_mode;
        err = lip_opcua_procbuf_get_uint32(buf, &sec_mode);
        if (err == LIP_OPCUA_ERR_GOOD) {
            params->securityMode = sec_mode;
        }
    }
    if (err == LIP_OPCUA_ERR_GOOD) {
        err = lip_opcua_procbuf_get_string(buf, &params->ClientNonce);

    }
    if (err == LIP_OPCUA_ERR_GOOD) {
        err = lip_opcua_procbuf_get_uint32(buf, &params->requestedLifetime);
    }
    return err;
}

t_lip_opcua_err lip_opcua_sc_open_resp_put(t_lip_proc_buf *buf, uint32_t proto_ver, const t_lip_opcua_sc_token *token, const t_lip_opcua_string_ptr *server_nonce) {
    t_lip_opcua_err err = lip_opcua_procbuf_put_uint32(buf, proto_ver);
    if (err == LIP_ERR_SUCCESS) {
        err = lip_opcua_procbuf_put_uint32(buf, token->SecureChannelId);
    }
    if (err == LIP_ERR_SUCCESS) {
        err = lip_opcua_procbuf_put_uint32(buf, token->TokenId);
    }
    if (err == LIP_ERR_SUCCESS) {
        err = lip_opcua_procbuf_put_datetime(buf, token->CreatedAt);
    }
    if (err == LIP_ERR_SUCCESS) {
        err = lip_opcua_procbuf_put_uint32(buf, token->RevisedLifetime);
    }
    if (err == LIP_ERR_SUCCESS) {
        err = lip_opcua_procbuf_put_string(buf, server_nonce);
    }
    return err;
}

t_lip_opcua_err lip_opcua_sc_msg_hdr_parse(t_lip_proc_buf *buf, t_lip_opcua_sc_msg_info *msg) {
    t_lip_opcua_err err = lip_opcua_procbuf_get_uint32(buf,  &msg->SecureChannelId);
    if (err == LIP_OPCUA_ERR_GOOD) {
        err = lip_opcua_procbuf_get_uint32(buf,  &msg->TockenId);
    }
    if (err == LIP_OPCUA_ERR_GOOD) {
        err = lip_opcua_procbuf_get_uint32(buf, &msg->SequenceNumber);
    }
    if (err == LIP_OPCUA_ERR_GOOD) {
        err = lip_opcua_procbuf_get_uint32(buf, &msg->RequestId);
    }
    return err;
}

t_lip_opcua_err lip_opcua_sc_msg_hdr_put(t_lip_proc_buf *buf, struct st_lip_opcua_sc_ctx *sc_ctx, uint32_t RequestId) {
    t_lip_opcua_err err = lip_opcua_procbuf_put_uint32(buf,  sc_ctx->cur_token.SecureChannelId);
    if (err == LIP_OPCUA_ERR_GOOD) {
        err = lip_opcua_procbuf_put_uint32(buf, sc_ctx->cur_token.TokenId);
    }
    if (err == LIP_OPCUA_ERR_GOOD) {
        err = lip_opcua_procbuf_put_uint32(buf, sc_ctx->tx_seq_num);
    }
    if (err == LIP_OPCUA_ERR_GOOD) {
        err = lip_opcua_procbuf_put_uint32(buf, RequestId);
    }
    return err;
}


#endif
