#include "dc_param.h"
#include "tinyxml2.h"

void dc_param_cfg_parse()
{
    using namespace tinyxml2;

    XMLDocument doc;
    if (XML_SUCCESS != doc.LoadFile(DC_PARAM_PATH))
    {
        MY_LOG_E("failed to load param file: %s", DC_PARAM_PATH);
        return;
    }

    XMLElement *root = doc.RootElement();
    if (nullptr == root)
    {
        MY_LOG_E("param file has no root element");
        return;
    }

    // 解析 Ao 段：单值参数（一份值 + 一份缺省值）
    XMLElement *ao_elem = root->FirstChildElement("Ao");
    if (ao_elem)
    {
        for (XMLElement *sig = ao_elem->FirstChildElement("Signal"); sig != nullptr;
             sig = sig->NextSiblingElement("Signal"))
        {
            const char *saddr = sig->Attribute("saddr");
            const char *desc = sig->Attribute("desc");
            const char *type_str = sig->Attribute("type");
            if (nullptr == saddr || nullptr == desc || nullptr == type_str)
            {
                MY_LOG_E("Ao Signal missing required attributes, skipping");
                continue;
            }

            uint8_t data_type = dc_get_data_type_id_by_str(type_str);
            if (0 == data_type)
            {
                MY_LOG_E("unknown data type %s for saddr %s", type_str, saddr);
                continue;
            }

            float min = sig->FloatAttribute("min", 0.0f);
            float max = sig->FloatAttribute("max", 0.0f);
            float step = sig->FloatAttribute("step", 0.0f);
            const char *unit = sig->Attribute("unit");

            // Ao 段：从 Signal 属性读取单值
            const char *val = sig->Attribute("value");
            const char *default_val = sig->Attribute("default");

            void *p_data = dc_create_data_ptr_by_type(data_type);
            if (p_data)
            {
                if (val && strlen(val) > 0)
                    dc_set_signal_val_from_str(p_data, data_type, std::string(val));
                else if (default_val && strlen(default_val) > 0)
                    dc_set_signal_val_from_str(p_data, data_type, std::string(default_val));
            }

            void *p_default_data = dc_create_data_ptr_by_type(data_type);
            if (p_default_data)
            {
                if (default_val && strlen(default_val) > 0)
                    dc_set_signal_val_from_str(p_default_data, data_type, std::string(default_val));
            }

            if (p_data && p_default_data)
            {
                stru_signal_param param;
                param.min = min;
                param.max = max;
                param.step = step;
                param.unit = unit ? std::string(unit) : std::string();

                dc_signal_ao(saddr, desc, data_type, param,
                                SIGNAL_CTRL_TYPE::SBO_NORMAL,
                                p_data, p_default_data, nullptr);
            }
        }
    }

    // 解析 Param 段：多值参数（多份值 + 多份缺省值）
    XMLElement *param_elem = root->FirstChildElement("Param");
    if (param_elem)
    {
        for (XMLElement *sig = param_elem->FirstChildElement("Signal"); sig != nullptr;
             sig = sig->NextSiblingElement("Signal"))
        {
            const char *saddr = sig->Attribute("saddr");
            const char *desc = sig->Attribute("desc");
            const char *type_str = sig->Attribute("type");
            if (nullptr == saddr || nullptr == desc || nullptr == type_str)
            {
                MY_LOG_E("Param Signal missing required attributes, skipping");
                continue;
            }

            uint8_t data_type = dc_get_data_type_id_by_str(type_str);
            if (0 == data_type)
            {
                MY_LOG_E("unknown data type %s for saddr %s", type_str, saddr);
                continue;
            }

            float min = sig->FloatAttribute("min", 0.0f);
            float max = sig->FloatAttribute("max", 0.0f);
            float step = sig->FloatAttribute("step", 0.0f);
            const char *unit = sig->Attribute("unit");

            std::vector<void *> vec_p_data;
            std::vector<void *> vec_p_default_data;

            int num = sig->IntAttribute("num", -1);
            if (num >= 1)
            {
                for (XMLElement *item = sig->FirstChildElement("Item"); item != nullptr;
                     item = item->NextSiblingElement("Item"))
                {
                    const char *val = item->Attribute("value");
                    const char *default_val = item->Attribute("default");

                    void *p_data = dc_create_data_ptr_by_type(data_type);
                    if (p_data)
                    {
                        if (val && strlen(val) > 0)
                            dc_set_signal_val_from_str(p_data, data_type, std::string(val));
                        else if (default_val && strlen(default_val) > 0)
                            dc_set_signal_val_from_str(p_data, data_type, std::string(default_val));
                        vec_p_data.push_back(p_data);
                    }

                    void *p_default_data = dc_create_data_ptr_by_type(data_type);
                    if (p_default_data)
                    {
                        if (default_val && strlen(default_val) > 0)
                            dc_set_signal_val_from_str(p_default_data, data_type, std::string(default_val));
                        vec_p_default_data.push_back(p_default_data);
                    }
                }

            }
            else
            {
                continue;
            }

            if (!vec_p_data.empty())
            {
                stru_signal_param param;
                param.min = min;
                param.max = max;
                param.step = step;
                param.unit = unit ? std::string(unit) : std::string();

                dc_signal_param(saddr, desc, data_type, param,
                                SIGNAL_CTRL_TYPE::SBO_NORMAL,
                                vec_p_data, vec_p_default_data, nullptr);
            }
        }
    }

   
}
