#include "upgrade_cfg.hpp"
#include <fstream>
#include <json/json.h>
#include <zlog.h>

extern zlog_category_t *zct;
extern zlog_category_t *zbt;

int UpgradeCfg::ReadCfg(std::map<int, UpgradeInfo> &upgrade) {
    std::ifstream upgrade_file(UPGRADE_CONFIG);
    if (!upgrade_file.good()) {
        zlog_info(zbt, "[UpgradeCfg] no such file");
        return 0;
    }
    upgrade_file.seekg(0, std::ios::end);
    std::streampos file_size = upgrade_file.tellg();
    if (file_size > 256000) {
        zlog_error(zct, "upgrade file exception, will remove it");
        ClearCfg();
        return 1;
    }
    upgrade_file.seekg(0, std::ios::beg);

    Json::Reader reader;
    Json::Value root;
    if (!reader.parse(upgrade_file, root, false)) {
        zlog_error(zbt, "[UpgradeCfg] invalid format, fail to parse %s", UPGRADE_CONFIG);
        upgrade_file.close();
        return 1;
    }
    upgrade_file.close();
    if (!root.isArray()) {
        zlog_error(zbt, "[UpgradeCfg] invalid format, not an array: %s", UPGRADE_CONFIG);
        return 2;
    }

    if (root.size() == 0) {
        zlog_info(zbt, "[UpgradeCfg] no element");
        return 0;
    }
    
    UpgradeInfo info;
    for (const auto &item : root) {
        info.try_times = item["try_times"].asInt();
        info.sensor_type = item["type"].asString();
        info.hw_version = item["hw_version"].asInt();
        info.current_sw_version = item["current_sw_version"].asString();
        info.upgrade_sw_version = item["upgrade_sw_version"].asString();
        info.submit_time = item["submit_time"].asString();
        for (const auto &time_item : item["try_world_time"]) {
            info.try_world_time1.push_back(time_item.asString());
        }
        upgrade[item["id"].asInt()] = info;
        zlog_info(zbt, "[UpgradeCfg] id:%d need to upgrade from:%s to %s", item["id"].asInt(), 
                info.current_sw_version.c_str(), info.upgrade_sw_version.c_str());
    }            
    
    return 0; 
}

int UpgradeCfg::WriteCfg(std::map<int, UpgradeInfo> &upgrade) {
    if (upgrade.size() == 0) {
        ClearCfg();
        return 0;
    }

    Json::Value root;        
    for (auto item : upgrade) {
        Json::Value upgrade_item;
        upgrade_item["id"] = item.first;
        upgrade_item["try_times"] = item.second.try_times;
        upgrade_item["type"] = item.second.sensor_type;
        upgrade_item["hw_version"] = item.second.hw_version;
        upgrade_item["current_sw_version"] = item.second.current_sw_version;
        upgrade_item["upgrade_sw_version"] = item.second.upgrade_sw_version;
        upgrade_item["submit_time"] = item.second.submit_time;
        Json::Value try_world_time;
        for (auto entry : item.second.try_world_time1) {
            try_world_time.append(entry);
        }
        upgrade_item["try_world_time"] = try_world_time;
        root.append(upgrade_item);
    }
    Json::StyledStreamWriter streamWriter;
    std::ofstream out_file(UPGRADE_CONFIG);
    streamWriter.write(out_file, root);
    out_file.close(); 
    return 0; 
}

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