#include <fstream>
#include <cstring>
#include <cstdint>
#include <string>
#include <fstream>
#include "utils.hpp"

namespace netcore {
// 辅助函数：将 py::dict 转为 nlohmann::json
json py_dict_to_json(py::dict d) {
    json j;
    for (auto item : d) {
        std::string key = py::str(item.first);
        py::object val = py::reinterpret_borrow<py::object>(item.second);

        if (py::isinstance<py::dict>(val)) {
            j[key] = py_dict_to_json(py::cast<py::dict>(val));
        } else if (py::isinstance<py::list>(val)) {
            py::list py_list = py::cast<py::list>(val);
            json arr = json::array();
            for (auto elem : py_list) {
                py::object elem_obj = py::reinterpret_borrow<py::object>(elem);
                if (py::isinstance<py::dict>(elem_obj)) {
                    arr.push_back(py_dict_to_json(py::cast<py::dict>(elem_obj)));
                } else if (py::isinstance<py::int_>(elem_obj)) {
                    arr.push_back(py::cast<int64_t>(elem_obj));
                } else if (py::isinstance<py::float_>(elem_obj)) {
                    arr.push_back(py::cast<double>(elem_obj));
                } else {
                    arr.push_back(py::str(elem_obj));
                }
            }
            j[key] = arr;
        } else if (py::isinstance<py::int_>(val)) {
            j[key] = py::cast<int64_t>(val);
        } else if (py::isinstance<py::float_>(val)) {
            j[key] = py::cast<double>(val);
        } else if (py::isinstance<py::bool_>(val)) {
            j[key] = py::cast<bool>(val);
        } else if (val.is_none()) {
            j[key] = nullptr;
        } else {
            j[key] = py::str(val);
        }
    }
    return j;
}

// 辅助函数：将 nlohmann::json 转为 py::dict
py::dict json_to_py_dict(const json& j) {
    py::dict d;
    if (j.is_object()) {
        for (auto& item : j.items()) {
            std::string key = item.key();
            json val = item.value();

            if (val.is_object()) {
                d[py::str(key)] = json_to_py_dict(val);
            } else if (val.is_array()) {
                py::list py_list;
                for (auto& elem : val) {
                    if (elem.is_object()) {
                        py_list.append(json_to_py_dict(elem));
                    } else if (elem.is_number_integer()) {
                        py_list.append(py::int_(elem.get<int64_t>()));
                    } else if (elem.is_number_float()) {
                        py_list.append(py::float_(elem.get<double>()));
                    } else if (elem.is_boolean()) {
                        py_list.append(py::bool_(elem.get<bool>()));
                    } else if (elem.is_null()) {
                        py_list.append(py::none());
                    } else {
                        py_list.append(py::str(elem.get<std::string>()));
                    }
                }
                d[py::str(key)] = py_list;
            } else if (val.is_number_integer()) {
                d[py::str(key)] = py::int_(val.get<int64_t>());
            } else if (val.is_number_float()) {
                d[py::str(key)] = py::float_(val.get<double>());
            } else if (val.is_boolean()) {
                d[py::str(key)] = py::bool_(val.get<bool>());
            } else if (val.is_null()) {
                d[py::str(key)] = py::none();
            } else {
                d[py::str(key)] = py::str(val.get<std::string>());
            }
        }
    }
    return d;
}



}