#ifndef LIP_OPCUA_STRING_H
#define LIP_OPCUA_STRING_H

#include "lip/lip_defs.h"
#include "lip/app/opcua/lip_opcua_cfg_defs.h"
#include <string.h>

typedef struct {
    int32_t size;
    const char *data;
} t_lip_opcua_string_ptr;

typedef struct {
    int32_t cnt;
    t_lip_opcua_string_ptr strlist[LIP_OPCUA_STRING_ARR_MAX_SIZE];
} t_lip_opcua_string_ptr_array;

typedef struct {
    t_lip_opcua_string_ptr locale;
    t_lip_opcua_string_ptr text;
} t_lip_opcua_loc_string_ptr;

typedef struct {
    t_lip_opcua_string_ptr strlist[LIP_OPCUA_LOCALE_CNT];
} t_lip_opcua_loc_string_ptr_list;

typedef struct {
    uint16_t ns_idx;
    t_lip_opcua_string_ptr name;
} t_lip_opcua_qualified_name;


#define LIP_OPCUA_EMPTY_STRING {.size = -1, .data = NULL}

static LINLINE bool lip_opcua_string_is_eq(const t_lip_opcua_string_ptr *s1, const t_lip_opcua_string_ptr *s2) {
    return (s1->size == s2->size) && ((s1->size <= 0) || (s1->data == s2->data) || (s1->data && s2->data && (memcmp(s1->data, s2->data, s1->size) == 0)));
}

static LINLINE bool lip_opcua_qname_is_eq(const t_lip_opcua_qualified_name *q1, const t_lip_opcua_qualified_name *q2) {
    return (q1->ns_idx == q2->ns_idx) && lip_opcua_string_is_eq(&q1->name, &q2->name);
}

static LINLINE void lip_opcua_string_init(t_lip_opcua_string_ptr *s1, const char *text, int32_t len) {
    if (text == NULL) {
        s1->data = NULL;
        s1->size = -1;
    } else {
        s1->data = text;
        s1->size = len >= 0 ? len : (int32_t)strlen(text);
    }
}

static LINLINE void lip_opcua_loctext_init(t_lip_opcua_loc_string_ptr_list *s1, const char *text, int32_t len) {
    for (unsigned loc_idx = 0; loc_idx < LIP_OPCUA_LOCALE_CNT; ++loc_idx) {
        lip_opcua_string_init(&s1->strlist[loc_idx], text, len);
    }
}

#endif // LIP_OPCUA_STRING_H
