#include "short_addr_cfg.hpp"
#include <fstream>
#include <json/json.h>
#include <zlog.h>
#include "common/common_func.hpp"

extern zlog_category_t *zct;
extern zlog_category_t *zbt;

int ShortAddrCfg::ReadCfg(std::map<uint16_t, int>& short_addr_map) {
    std::ifstream base_relation_file(BASE_RELATION);
    if (!base_relation_file.good()) {
        zlog_info(zbt, "[ShortAddrCfg] no file %s", BASE_RELATION);
        return 0;
    }
    Json::Reader reader;
    Json::Value root;
    if (!reader.parse(base_relation_file, root, false)) {
        zlog_error(zbt, "[ShortAddrCfg] invalid format, fail to parse %s", BASE_RELATION);
        base_relation_file.close();
        return 1;
    }
    base_relation_file.close();
    if (!root.isArray()) {
        zlog_error(zbt, "[ShortAddrCfg] invalid format, not an array: %s", BASE_RELATION);
        return 2;
    }
    if (root.size() == 0) {
        zlog_info(zbt, "[ShortAddrCfg] no element in %s", BASE_RELATION);
        return 0;
    }

    uint16_t short_addr;
    int index = 0;       
    std::string short_addr_str;
    char *end_ptr;
    for (const auto &item : root) {
        short_addr_str = item["short_addr"].asString();
        short_addr = strtol(short_addr_str.c_str(), &end_ptr, 16);
        index = item["id"].asInt();
        zlog_info(zbt, "[ShortAddrCfg] index:%d, short addr:%02x", index, short_addr);
        short_addr_map[short_addr] = index;
    }    
    return 0; 
}

int ShortAddrCfg::WriteCfg(std::map<uint16_t, int> &short_addr_map) { 
    Json::Value root; 
    char buf[8] = {0};
    for (auto it = short_addr_map.begin(); it != short_addr_map.end(); ++it) {
        Json::Value item;
        item["id"] = it->second;
        memset(buf, 0, 8);
        snprintf(buf, 8, "%02x%02x", UINT16_HIGH(it->first),UINT16_LOW(it->first));
        item["short_addr"] = buf;
        root.append(item);
    }
    Json::StyledStreamWriter streamWriter;
    std::ofstream out_file(BASE_RELATION);
    streamWriter.write(out_file, root);
    return 0; 
}

void ShortAddrCfg::ClearCfg() {
    std::string clear_cmd = "rm -rf ";
    clear_cmd.append(BASE_RELATION);
    system(clear_cmd.c_str());
}
