#include "lip/app/opcua/server/lip_opcua_server_cfg_defs.h"
#if LIP_OPCUA_SERVER_ENABLE
#include "lip_opcua_server_tree_server_obj.h"
#include "lip_opcua_server_tree_folders.h"
#include "lip_opcua_server_tree_modeling_rules.h"
#include "../types/lip_opcua_server_tree_std_datatypes.h"
#include "../types/lip_opcua_server_tree_std_objtypes.h"
#include "../types/lip_opcua_server_tree_std_vartypes.h"
#include "../lip_opcua_server_tree_std_var_descr.h"
#include "../types/lip_opcua_server_tree_reftypes.h"
#include "../lip_opcua_server_tree_decl_defs.h"
#include "../types/groups/lip_opcua_server_tree_std_types_struct.h"
#include "../types/groups/lip_opcua_server_tree_std_types_buildinfo.h"
#include "../types/groups/lip_opcua_server_tree_std_types_server.h"
#include "../types/groups/lip_opcua_server_tree_std_types_server_status.h"
#include "../types/lip_opcua_server_tree_std_datatypes_descr.h"
#include "lip/app/opcua/server/tree/lip_opcua_tree_item.h"
#include "lip/app/opcua/server/tree/lip_opcua_tree_item_ref.h"
#include "lip/app/opcua/server/lip_opcua_server_params.h"
#include "lip/app/opcua/lip_opcua_err_codes.h"
#include "lip/app/opcua/lip_opcua_std_nodeids.h"
#include "lip/app/opcua/types/struct/lip_opcua_server_status.h"
#include "lip/app/opcua/server/lip_opcua_server_time.h"
#include "lip/misc/lip_misc_build_time.h"

#define LIP_OPCUA_SERVER_NAMESPACES_CNT     2

static t_lip_opcua_string_ptr f_namespace_list[LIP_OPCUA_SERVER_NAMESPACES_CNT];
static uint8_t f_namespaces_cnt;
static t_lip_opcua_data_server_status f_server_status;
static t_lip_opcua_data_build_info f_server_build_info = {
    .product_uri.size = -1,
    .manufacturer_name.size = -1,
    .product_name.size = -1,
#ifdef LIP_OPCUA_SERVER_VERSION_STR
    .software_version.data = LIP_OPCUA_SERVER_VERSION_STR,
    .software_version.size = sizeof(LIP_OPCUA_SERVER_VERSION_STR)-1,
#else
    .software_version.size = -1,
#endif
    .build_number.size = -1,
    .build_date = (UNIX_TIMESTAMP + LIP_OPCUA_TSTMP_SEC_TO_UNIX_EPOCH) * LIP_OPCUA_TSTMP_TICK_SEC
};

void lip_opcua_server_obj_init(void) {
    lip_opcua_string_init(&f_namespace_list[LIP_OPCUA_NAMESPACE_IDX_OPCUA], LIP_OPCUA_NAMESPACE_NAME_OPCUA, sizeof(LIP_OPCUA_NAMESPACE_NAME_OPCUA)-1);
    if (f_namespaces_cnt < (LIP_OPCUA_NAMESPACE_IDX_OPCUA+1)) {
        f_namespaces_cnt = LIP_OPCUA_NAMESPACE_IDX_OPCUA+1;
    }

    f_server_status.server_state = LIP_OPCUA_SERVER_STATE_RUNNING;
    f_server_status.build_info = &f_server_build_info;


}

void lip_opcua_server_set_server_uri(const char *uri, int32_t len) {
    lip_opcua_string_init(&f_namespace_list[LIP_OPCUA_NAMESPACE_IDX_LOCAL_SERVER], uri, len);
    if (f_namespaces_cnt < (LIP_OPCUA_NAMESPACE_IDX_LOCAL_SERVER+1)) {
        f_namespaces_cnt = LIP_OPCUA_NAMESPACE_IDX_LOCAL_SERVER+1;
    }
}

void lip_opcua_server_set_manufacturer(const char *name, int32_t len) {
    lip_opcua_string_init(&f_server_build_info.manufacturer_name, name, len);
}

void lip_opcua_server_set_sw_name(const char *name, int32_t len) {
    lip_opcua_string_init(&f_server_build_info.product_name, name, len);
}

void lip_opcua_server_set_sw_uri(const char *name, int32_t len) {
    lip_opcua_string_init(&f_server_build_info.product_uri, name, len);
}




static t_lip_opcua_err f_server_status_read(const struct st_lip_opcua_tree_item *item, struct st_lip_opcua_session_ctx *session, const t_lip_opcua_item_read_params *params, t_lip_opcua_data_value *val) {

    t_lip_opcua_tstmp tstmp;
    lip_opcua_get_cur_tstmp(&tstmp);
    f_server_status.current_time = tstmp.ns100;
    f_server_status.start_time = lip_opcua_server_start_time();

    lip_opcua_variant_set_extobj(&val->value, &g_lip_opcua_tree_std_item_datatype_server_status.nodeid, &f_server_status);


    return LIP_OPCUA_ERR_GOOD;
}

static t_lip_opcua_err f_server_status_start_time_read(const struct st_lip_opcua_tree_item *item, struct st_lip_opcua_session_ctx *session, const t_lip_opcua_item_read_params *params, t_lip_opcua_data_value *val) {
    lip_opcua_variant_set_datetime(&val->value, lip_opcua_server_start_time());
    return LIP_OPCUA_ERR_GOOD;
}

static t_lip_opcua_err f_server_status_current_time_read(const struct st_lip_opcua_tree_item *item, struct st_lip_opcua_session_ctx *session, const t_lip_opcua_item_read_params *params, t_lip_opcua_data_value *val) {
    t_lip_opcua_tstmp tstmp;
    lip_opcua_get_cur_tstmp(&tstmp);
    lip_opcua_variant_set_datetime(&val->value, tstmp.ns100);
    return LIP_OPCUA_ERR_GOOD;
}

static t_lip_opcua_err f_server_status_state_read(const struct st_lip_opcua_tree_item *item, struct st_lip_opcua_session_ctx *session, const t_lip_opcua_item_read_params *params, t_lip_opcua_data_value *val) {
    lip_opcua_variant_set_enum(&val->value, f_server_status.server_state);
    return LIP_OPCUA_ERR_GOOD;
}


static t_lip_opcua_err f_server_status_build_info_read(const struct st_lip_opcua_tree_item *item, struct st_lip_opcua_session_ctx *session, const t_lip_opcua_item_read_params *params, t_lip_opcua_data_value *val) {
    lip_opcua_variant_set_extobj(&val->value, &g_lip_opcua_tree_std_item_datatype_build_info.nodeid, &f_server_build_info);
    return LIP_OPCUA_ERR_GOOD;
}

static t_lip_opcua_err f_server_status_build_info_product_uri_read(const struct st_lip_opcua_tree_item *item, struct st_lip_opcua_session_ctx *session, const t_lip_opcua_item_read_params *params, t_lip_opcua_data_value *val) {
    lip_opcua_variant_set_str(&val->value, &f_server_build_info.product_uri);
    return LIP_OPCUA_ERR_GOOD;
}

static t_lip_opcua_err f_server_status_build_info_manufacturer_name_read(const struct st_lip_opcua_tree_item *item, struct st_lip_opcua_session_ctx *session, const t_lip_opcua_item_read_params *params, t_lip_opcua_data_value *val) {
    lip_opcua_variant_set_str(&val->value, &f_server_build_info.manufacturer_name);
    return LIP_OPCUA_ERR_GOOD;
}

static t_lip_opcua_err f_server_status_build_info_product_name_read(const struct st_lip_opcua_tree_item *item, struct st_lip_opcua_session_ctx *session, const t_lip_opcua_item_read_params *params, t_lip_opcua_data_value *val) {
    lip_opcua_variant_set_str(&val->value, &f_server_build_info.product_name);
    return LIP_OPCUA_ERR_GOOD;
}

static t_lip_opcua_err f_server_status_build_info_software_version_read(const struct st_lip_opcua_tree_item *item, struct st_lip_opcua_session_ctx *session, const t_lip_opcua_item_read_params *params, t_lip_opcua_data_value *val) {
    lip_opcua_variant_set_str(&val->value, &f_server_build_info.software_version);
    return LIP_OPCUA_ERR_GOOD;
}

static t_lip_opcua_err f_server_status_build_info_build_number_read(const struct st_lip_opcua_tree_item *item, struct st_lip_opcua_session_ctx *session, const t_lip_opcua_item_read_params *params, t_lip_opcua_data_value *val) {
    lip_opcua_variant_set_str(&val->value, &f_server_build_info.build_number);
    return LIP_OPCUA_ERR_GOOD;
}

static t_lip_opcua_err f_server_status_build_info_build_date_read(const struct st_lip_opcua_tree_item *item, struct st_lip_opcua_session_ctx *session, const t_lip_opcua_item_read_params *params, t_lip_opcua_data_value *val) {
    lip_opcua_variant_set_datetime(&val->value, f_server_build_info.build_date);
    return LIP_OPCUA_ERR_GOOD;
}





/*----------- Server object ----------------------------------------------------*/
static const t_lip_opcua_tree_item *f_server_properties[] = {
    &g_lip_opcua_tree_std_item_server_server_array,
    &g_lip_opcua_tree_std_item_server_ns_array,
    &g_lip_opcua_tree_std_item_server_service_level,
};

static const t_lip_opcua_tree_item *f_server_components[] = {
    &g_lip_opcua_tree_std_item_server_status,
};


static const t_lip_opcua_tree_item_ref_descr f_obj_server_refs[] = {
    LIP_OPCUA_TREE_REF_DECL_SINGLE_FWD(g_lip_opcua_tree_std_item_reftype_has_type_definition, g_lip_opcua_tree_std_item_server_type) LIP_OPCUA_TREE_REF_DECL_NEXT
    LIP_OPCUA_TREE_REF_DECL_SINGLE_INV(g_lip_opcua_tree_std_item_reftype_organizes, g_lip_opcua_tree_std_item_objects_folder) LIP_OPCUA_TREE_REF_DECL_NEXT
    LIP_OPCUA_TREE_REF_DECL_MULTI_FWD(g_lip_opcua_tree_std_item_reftype_has_property, f_server_properties) LIP_OPCUA_TREE_REF_DECL_NEXT
    LIP_OPCUA_TREE_REF_DECL_MULTI_FWD(g_lip_opcua_tree_std_item_reftype_has_component, f_server_components)
    LIP_OPCUA_TREE_REF_DECL_END
};

static const t_lip_opcua_tree_item_descr_object f_item_obj_server_descr = {
    LIP_OPCUA_TREE_ITEM_OBJECT_INIT
        .evt_notifier_flags = 0,
};


const t_lip_opcua_tree_item g_lip_opcua_tree_std_item_server_obj = {
    .nodeid = LIP_OPCUA_NODEID_STDNS_INT(LIP_OPCUA_NODEID_STD_SERVER),
    LIP_OPCUA_TREE_ITEM_FILL_STD_BROWSE_NAME("Server"),
    .refs = f_obj_server_refs,
    .class_descr_hdr = &f_item_obj_server_descr.hdr
};



t_lip_opcua_err f_server_servers_array_read(const struct st_lip_opcua_tree_item *item, struct st_lip_opcua_session_ctx *session, const t_lip_opcua_item_read_params *params, t_lip_opcua_data_value *val) {
    /* используем тут файт, что server uri и ns1 имя должны быть одинаковы. внешние серверы неподдерживаем */
    lip_opcua_variant_set_array_str(&val->value, &f_namespace_list[LIP_OPCUA_NAMESPACE_IDX_LOCAL_SERVER], 1);
    return LIP_OPCUA_ERR_GOOD;
}

t_lip_opcua_err f_server_ns_array_read(const struct st_lip_opcua_tree_item *item, struct st_lip_opcua_session_ctx *session, const t_lip_opcua_item_read_params *params, t_lip_opcua_data_value *val) {
    lip_opcua_variant_set_array_str(&val->value, &f_namespace_list[0], f_namespaces_cnt);
    return LIP_OPCUA_ERR_GOOD;
}



static const t_lip_opcua_tree_item_ref_descr f_server_property_refs[] = {
    LIP_OPCUA_TREE_REF_DECL_SINGLE_INV(g_lip_opcua_tree_std_item_reftype_has_property, g_lip_opcua_tree_std_item_server_obj) LIP_OPCUA_TREE_REF_DECL_NEXT
    LIP_OPCUA_TREE_REF_DECL_SINGLE_FWD(g_lip_opcua_tree_std_item_reftype_has_type_definition, g_lip_opcua_tree_std_item_vartype_property)
    LIP_OPCUA_TREE_REF_DECL_END
};


static const t_lip_opcua_tree_item_descr_variable f_server_server_array_descr = {
    LIP_OPCUA_TREE_ITEM_VAR_INIT
     .data_descr = &g_lip_opcua_tree_std_data_descr_str_arr,
    .cbs.acc.value_read = &f_server_servers_array_read
};

const t_lip_opcua_tree_item g_lip_opcua_tree_std_item_server_server_array = {
    .nodeid = LIP_OPCUA_NODEID_STDNS_INT(LIP_OPCUA_NODEID_STD_SERVER_SERVER_ARRAY),
    LIP_OPCUA_TREE_ITEM_FILL_STD_BROWSE_NAME("ServerArray"),
    .refs = f_server_property_refs,
    .class_descr_hdr = &f_server_server_array_descr.hdr
};


static const t_lip_opcua_tree_item_descr_variable f_item_namespace_arr = {
    LIP_OPCUA_TREE_ITEM_VAR_INIT
    .data_descr = &g_lip_opcua_tree_std_data_descr_str_arr,
    .cbs.acc.value_read = &f_server_ns_array_read
};

const t_lip_opcua_tree_item g_lip_opcua_tree_std_item_server_ns_array = {
    .nodeid = LIP_OPCUA_NODEID_STDNS_INT(LIP_OPCUA_NODEID_STD_SERVER_NAMESPACE_ARRAY),
    LIP_OPCUA_TREE_ITEM_FILL_STD_BROWSE_NAME("NamespaceArray"),
    .refs = f_server_property_refs,
    .class_descr_hdr = &f_item_namespace_arr.hdr
};


const t_lip_opcua_tree_item g_lip_opcua_tree_std_item_server_service_level = {
    .nodeid = LIP_OPCUA_NODEID_STDNS_INT(LIP_OPCUA_NODEID_STD_SERVER_SERVICE_LEVEL),
    LIP_OPCUA_TREE_ITEM_FILL_STD_BROWSE_NAME("ServiceLevel"),
    .refs = f_server_property_refs,
    LIP_OPCUA_TREE_ITEM_FILL_VAR_CONST_UINT8(LIP_OPCUA_SERVER_DEFAULT_SERVICE_LEVEL)
};


/*----------- ServerStatus ---------------------------------------------------*/
static const t_lip_opcua_tree_item *f_server_status_components[] = {
    &g_lip_opcua_tree_std_item_server_status_start_time,
    &g_lip_opcua_tree_std_item_server_status_current_time,
    &g_lip_opcua_tree_std_item_server_status_state,
    &g_lip_opcua_tree_std_item_server_status_build_info,
    &g_lip_opcua_tree_std_item_server_status_secs_till_shutdown,
    &g_lip_opcua_tree_std_item_server_status_shutdown_reason,
};


static const t_lip_opcua_tree_item_ref_descr f_server_status_refs[] = {
    LIP_OPCUA_TREE_REF_DECL_SINGLE_INV(g_lip_opcua_tree_std_item_reftype_has_component, g_lip_opcua_tree_std_item_server_obj) LIP_OPCUA_TREE_REF_DECL_NEXT
    LIP_OPCUA_TREE_REF_DECL_SINGLE_FWD(g_lip_opcua_tree_std_item_reftype_has_type_definition, g_lip_opcua_tree_std_item_vartype_server_status) LIP_OPCUA_TREE_REF_DECL_NEXT
    LIP_OPCUA_TREE_REF_DECL_MULTI_FWD(g_lip_opcua_tree_std_item_reftype_has_component, f_server_status_components)
    LIP_OPCUA_TREE_REF_DECL_END
};

static const struct st_lip_opcua_tree_item_descr_variable f_server_status_descr = {
    LIP_OPCUA_TREE_ITEM_VAR_INIT
    .data_descr = &g_lip_opcua_tree_std_data_descr_server_status,
    .cbs.acc.value_read = &f_server_status_read
};


const t_lip_opcua_tree_item g_lip_opcua_tree_std_item_server_status = {
    .nodeid = LIP_OPCUA_NODEID_STDNS_INT(LIP_OPCUA_NODEID_STD_SERVER_SERVER_STATUS),
    LIP_OPCUA_TREE_ITEM_FILL_STD_BROWSE_NAME("ServerStatus"),
    .refs = f_server_status_refs,
    .class_descr_hdr = &f_server_status_descr.hdr
};

static const t_lip_opcua_tree_item_ref_descr f_server_status_component_refs[] = {
    LIP_OPCUA_TREE_REF_DECL_SINGLE_INV(g_lip_opcua_tree_std_item_reftype_has_component, g_lip_opcua_tree_std_item_server_status) LIP_OPCUA_TREE_REF_DECL_NEXT
    LIP_OPCUA_TREE_REF_DECL_SINGLE_FWD(g_lip_opcua_tree_std_item_reftype_has_type_definition, g_lip_opcua_tree_std_item_vartype_base_data_variable)
    LIP_OPCUA_TREE_REF_DECL_END
};

/*----------- ServerStatus StartTime -----------------------------------------*/
static const struct st_lip_opcua_tree_item_descr_variable f_server_status_start_time_descr = {
    LIP_OPCUA_TREE_ITEM_VAR_INIT
    .data_descr = &g_lip_opcua_tree_std_data_descr_utc_time,
    .cbs.acc.value_read = &f_server_status_start_time_read
};

const t_lip_opcua_tree_item g_lip_opcua_tree_std_item_server_status_start_time = {
    .nodeid = LIP_OPCUA_NODEID_STDNS_INT(LIP_OPCUA_NODEID_STD_SERVER_STATUS_START_TIME),
    LIP_OPCUA_TREE_ITEM_FILL_STD_BROWSE_NAME("StartTime"),
    .refs = f_server_status_component_refs,
    .class_descr_hdr = &f_server_status_start_time_descr.hdr
};

/*----------- ServerStatus CurrentTime ---------------------------------------*/
static const struct st_lip_opcua_tree_item_descr_variable f_server_status_current_time_descr = {
    LIP_OPCUA_TREE_ITEM_VAR_INIT
    .data_descr = &g_lip_opcua_tree_std_data_descr_utc_time,
    .cbs.acc.value_read = &f_server_status_current_time_read
};

const t_lip_opcua_tree_item g_lip_opcua_tree_std_item_server_status_current_time = {
    .nodeid = LIP_OPCUA_NODEID_STDNS_INT(LIP_OPCUA_NODEID_STD_SERVER_STATUS_CURRENT_TIME),
    LIP_OPCUA_TREE_ITEM_FILL_STD_BROWSE_NAME("CurrentTime"),
    .refs = f_server_status_component_refs,
    .class_descr_hdr = &f_server_status_current_time_descr.hdr
};


/*----------- ServerStatus State ---------------------------------------------*/
static const struct st_lip_opcua_tree_item_descr_variable f_server_status_state_descr = {
    LIP_OPCUA_TREE_ITEM_VAR_INIT
    .data_descr = &g_lip_opcua_tree_std_data_descr_server_state,
    .cbs.acc.value_read = &f_server_status_state_read
};

const t_lip_opcua_tree_item g_lip_opcua_tree_std_item_server_status_state = {
    .nodeid = LIP_OPCUA_NODEID_STDNS_INT(LIP_OPCUA_NODEID_STD_SERVER_STATUS_STATE),
    LIP_OPCUA_TREE_ITEM_FILL_STD_BROWSE_NAME("State"),
    .refs = f_server_status_component_refs,
    .class_descr_hdr = &f_server_status_state_descr.hdr
};





/*----------- ServerStatus BuildInfo -----------------------------------------*/
static const t_lip_opcua_tree_item *f_server_status_build_info_components[] = {
    &g_lip_opcua_tree_std_item_server_status_build_info_product_uri,
    &g_lip_opcua_tree_std_item_server_status_build_info_manufacturer_name,
    &g_lip_opcua_tree_std_item_server_status_build_info_product_name,
    &g_lip_opcua_tree_std_item_server_status_build_info_software_version,
    &g_lip_opcua_tree_std_item_server_status_build_info_build_number,
    &g_lip_opcua_tree_std_item_server_status_build_info_build_date,
};

static const t_lip_opcua_tree_item_ref_descr f_server_status_build_info_refs[] = {
    LIP_OPCUA_TREE_REF_DECL_SINGLE_INV(g_lip_opcua_tree_std_item_reftype_has_component, g_lip_opcua_tree_std_item_server_status) LIP_OPCUA_TREE_REF_DECL_NEXT
    LIP_OPCUA_TREE_REF_DECL_SINGLE_FWD(g_lip_opcua_tree_std_item_reftype_has_type_definition, g_lip_opcua_tree_std_item_vartype_build_info) LIP_OPCUA_TREE_REF_DECL_NEXT
    LIP_OPCUA_TREE_REF_DECL_MULTI_FWD(g_lip_opcua_tree_std_item_reftype_has_component, f_server_status_build_info_components)
    LIP_OPCUA_TREE_REF_DECL_END
};

static const struct st_lip_opcua_tree_item_descr_variable f_server_status_state_build_info_descr = {
    LIP_OPCUA_TREE_ITEM_VAR_INIT
    .data_descr = &g_lip_opcua_tree_std_data_descr_build_info,
    .cbs.acc.value_read = &f_server_status_build_info_read
};

const t_lip_opcua_tree_item g_lip_opcua_tree_std_item_server_status_build_info = {
    .nodeid = LIP_OPCUA_NODEID_STDNS_INT(LIP_OPCUA_NODEID_STD_SERVER_STATUS_BUILD_INFO),
    LIP_OPCUA_TREE_ITEM_FILL_STD_BROWSE_NAME("BuildInfo"),
    .refs = f_server_status_build_info_refs,
    .class_descr_hdr = &f_server_status_state_build_info_descr.hdr
};

static const t_lip_opcua_tree_item_ref_descr f_server_status_build_info_component_refs[] = {
    LIP_OPCUA_TREE_REF_DECL_SINGLE_INV(g_lip_opcua_tree_std_item_reftype_has_component, g_lip_opcua_tree_std_item_server_status_build_info) LIP_OPCUA_TREE_REF_DECL_NEXT
    LIP_OPCUA_TREE_REF_DECL_SINGLE_FWD(g_lip_opcua_tree_std_item_reftype_has_type_definition, g_lip_opcua_tree_std_item_vartype_base_data_variable)
    LIP_OPCUA_TREE_REF_DECL_END
};

/*----------- ServerStatus BuildInfo ProductUri ------------------------------*/
static const struct st_lip_opcua_tree_item_descr_variable f_server_status_state_build_info_product_uri_descr = {
    LIP_OPCUA_TREE_ITEM_VAR_INIT
    .data_descr = &g_lip_opcua_tree_std_data_descr_str,
    .cbs.acc.value_read = &f_server_status_build_info_product_uri_read
};

const t_lip_opcua_tree_item g_lip_opcua_tree_std_item_server_status_build_info_product_uri = {
    .nodeid = LIP_OPCUA_NODEID_STDNS_INT(LIP_OPCUA_NODEID_STD_SERVER_STATUS_BUILD_INFO_PRODUCT_URI),
    LIP_OPCUA_TREE_ITEM_FILL_STD_BROWSE_NAME("ProductUri"),
    .refs = f_server_status_build_info_component_refs,
    .class_descr_hdr = &f_server_status_state_build_info_product_uri_descr.hdr
};

/*----------- ServerStatus BuildInfo ManufacturerName ------------------------------*/
static const struct st_lip_opcua_tree_item_descr_variable f_server_status_state_build_info_manufacturer_name_descr = {
    LIP_OPCUA_TREE_ITEM_VAR_INIT
    .data_descr = &g_lip_opcua_tree_std_data_descr_str,
    .cbs.acc.value_read = &f_server_status_build_info_manufacturer_name_read
};

const t_lip_opcua_tree_item g_lip_opcua_tree_std_item_server_status_build_info_manufacturer_name = {
    .nodeid = LIP_OPCUA_NODEID_STDNS_INT(LIP_OPCUA_NODEID_STD_SERVER_STATUS_BUILD_INFO_MANUFACTURER_NAME),
    LIP_OPCUA_TREE_ITEM_FILL_STD_BROWSE_NAME("ManufacturerName"),
    .refs = f_server_status_build_info_component_refs,
    .class_descr_hdr = &f_server_status_state_build_info_manufacturer_name_descr.hdr
};

/*----------- ServerStatus BuildInfo ProductName ------------------------------*/
static const struct st_lip_opcua_tree_item_descr_variable f_server_status_state_build_info_product_name_descr = {
    LIP_OPCUA_TREE_ITEM_VAR_INIT
    .data_descr = &g_lip_opcua_tree_std_data_descr_str,
    .cbs.acc.value_read = &f_server_status_build_info_product_name_read
};

const t_lip_opcua_tree_item g_lip_opcua_tree_std_item_server_status_build_info_product_name = {
    .nodeid = LIP_OPCUA_NODEID_STDNS_INT(LIP_OPCUA_NODEID_STD_SERVER_STATUS_BUILD_INFO_PRODUCT_NAME),
    LIP_OPCUA_TREE_ITEM_FILL_STD_BROWSE_NAME("ProductName"),
    .refs = f_server_status_build_info_component_refs,
    .class_descr_hdr = &f_server_status_state_build_info_product_name_descr.hdr
};

/*----------- ServerStatus BuildInfo SoftwareVersion ------------------------------*/
static const struct st_lip_opcua_tree_item_descr_variable f_server_status_state_build_info_software_version_descr = {
    LIP_OPCUA_TREE_ITEM_VAR_INIT
    .data_descr = &g_lip_opcua_tree_std_data_descr_str,
    .cbs.acc.value_read = &f_server_status_build_info_software_version_read
};

const t_lip_opcua_tree_item g_lip_opcua_tree_std_item_server_status_build_info_software_version = {
    .nodeid = LIP_OPCUA_NODEID_STDNS_INT(LIP_OPCUA_NODEID_STD_SERVER_STATUS_BUILD_INFO_SOFTWARE_VERSION),
    LIP_OPCUA_TREE_ITEM_FILL_STD_BROWSE_NAME("SoftwareVersion"),
    .refs = f_server_status_build_info_component_refs,
    .class_descr_hdr = &f_server_status_state_build_info_software_version_descr.hdr
};

/*----------- ServerStatus BuildInfo BuildNumber ------------------------------*/
static const struct st_lip_opcua_tree_item_descr_variable f_server_status_state_build_info_build_number_descr = {
    LIP_OPCUA_TREE_ITEM_VAR_INIT
    .data_descr = &g_lip_opcua_tree_std_data_descr_str,
    .cbs.acc.value_read = &f_server_status_build_info_build_number_read
};

const t_lip_opcua_tree_item g_lip_opcua_tree_std_item_server_status_build_info_build_number = {
    .nodeid = LIP_OPCUA_NODEID_STDNS_INT(LIP_OPCUA_NODEID_STD_SERVER_STATUS_BUILD_INFO_BUILD_NUMBER),
    LIP_OPCUA_TREE_ITEM_FILL_STD_BROWSE_NAME("BuildNumber"),
    .refs = f_server_status_build_info_component_refs,
    .class_descr_hdr = &f_server_status_state_build_info_build_number_descr.hdr
};

/*----------- ServerStatus BuildInfo BuildNumber ------------------------------*/
static const struct st_lip_opcua_tree_item_descr_variable f_server_status_state_build_info_build_date_descr = {
    LIP_OPCUA_TREE_ITEM_VAR_INIT
    .data_descr = &g_lip_opcua_tree_std_data_descr_utc_time,
    .cbs.acc.value_read = &f_server_status_build_info_build_date_read
};

const t_lip_opcua_tree_item g_lip_opcua_tree_std_item_server_status_build_info_build_date = {
    .nodeid = LIP_OPCUA_NODEID_STDNS_INT(LIP_OPCUA_NODEID_STD_SERVER_STATUS_BUILD_INFO_BUILD_DATE),
    LIP_OPCUA_TREE_ITEM_FILL_STD_BROWSE_NAME("BuildDate"),
    .refs = f_server_status_build_info_component_refs,
    .class_descr_hdr = &f_server_status_state_build_info_build_date_descr.hdr
};



/*----------- ServerStatus SecondsTillShutdown ---------------------------------------------*/
const t_lip_opcua_tree_item g_lip_opcua_tree_std_item_server_status_secs_till_shutdown = {
    .nodeid = LIP_OPCUA_NODEID_STDNS_INT(LIP_OPCUA_NODEID_STD_SERVER_STATUS_SECONDS_TILL_SHUTDOWN),
    LIP_OPCUA_TREE_ITEM_FILL_STD_BROWSE_NAME("SecondsTillShutdown"),
    .refs = f_server_status_component_refs,
    LIP_OPCUA_TREE_ITEM_FILL_VAR_CONST_UINT32(0)
};

/*----------- ServerStatus ShutdownReason ---------------------------------------------*/
static const t_lip_opcua_loc_string_ptr_list f_shutdown_reason_placehoder[] = {};

const t_lip_opcua_tree_item g_lip_opcua_tree_std_item_server_status_shutdown_reason = {
    .nodeid = LIP_OPCUA_NODEID_STDNS_INT(LIP_OPCUA_NODEID_STD_SERVER_STATUS_SHUTDOWN_REASON),
    LIP_OPCUA_TREE_ITEM_FILL_STD_BROWSE_NAME("ShutdownReason"),
    .refs = f_server_status_component_refs,
    LIP_OPCUA_TREE_ITEM_FILL_VAR_CONST_LOCTEXT_ARR(f_shutdown_reason_placehoder)
};


#endif

