#include "dbus_interface.hpp"

#include "perform_probe.hpp"
#include "utils.hpp"

#include <boost/algorithm/string/case_conv.hpp>
#include <boost/container/flat_map.hpp>

#include <fstream>
#include <regex>
#include <string>
#include <vector>

using JsonVariantType =
    std::variant<std::vector<std::string>, std::vector<double>, std::string,
                 int64_t, uint64_t, double, int32_t, uint32_t, int16_t,
                 uint16_t, uint8_t, bool>;

namespace dbus_interface
{

const std::regex illegalDbusPathRegex("[^A-Za-z0-9_.]");
const std::regex illegalDbusMemberRegex("[^A-Za-z0-9_]");

// NOLINTBEGIN(cppcoreguidelines-avoid-non-const-global-variables)
// store reference to all interfaces so we can destroy them later
boost::container::flat_map<
    std::string, std::vector<std::weak_ptr<sdbusplus::asio::dbus_interface>>>
    inventory;
// NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables)

void tryIfaceInitialize(std::shared_ptr<sdbusplus::asio::dbus_interface>& iface)
{
    try
    {
        iface->initialize();
    }
    catch (std::exception& e)
    {
        std::cerr << "Unable to initialize dbus interface : " << e.what()
                  << "\n"
                  << "object Path : " << iface->get_object_path() << "\n"
                  << "interface name : " << iface->get_interface_name() << "\n";
    }
}

std::shared_ptr<sdbusplus::asio::dbus_interface> createInterface(
    sdbusplus::asio::object_server& objServer, const std::string& path,
    const std::string& interface, const std::string& parent, bool checkNull)
{
    // on first add we have no reason to check for null before add, as there
    // won't be any. For dynamically added interfaces, we check for null so that
    // a constant delete/add will not create a memory leak

    auto ptr = objServer.add_interface(path, interface);
    auto& dataVector = inventory[parent];
    if (checkNull)
    {
        auto it = std::find_if(dataVector.begin(), dataVector.end(),
                               [](const auto& p) { return p.expired(); });
        if (it != dataVector.end())
        {
            *it = ptr;
            return ptr;
        }
    }
    dataVector.emplace_back(ptr);
    return ptr;
}

void createDeleteObjectMethod(
    const std::string& jsonPointerPath,
    const std::shared_ptr<sdbusplus::asio::dbus_interface>& iface,
    sdbusplus::asio::object_server& objServer,
    nlohmann::json& systemConfiguration, boost::asio::io_context& io)
{
    std::weak_ptr<sdbusplus::asio::dbus_interface> interface = iface;
    iface->register_method(
        "Delete", [&objServer, &systemConfiguration, interface,
                   jsonPointerPath{std::string(jsonPointerPath)}, &io]() {
            std::shared_ptr<sdbusplus::asio::dbus_interface> dbusInterface =
                interface.lock();
            if (!dbusInterface)
            {
                // this technically can't happen as the pointer is pointing to
                // us
                throw DBusInternalError();
            }
            nlohmann::json::json_pointer ptr(jsonPointerPath);
            systemConfiguration[ptr] = nullptr;

            // todo(james): dig through sdbusplus to find out why we can't
            // delete it in a method call
            boost::asio::post(io, [&objServer, dbusInterface]() mutable {
                objServer.remove_interface(dbusInterface);
            });

            if (!configuration::writeJsonFiles(systemConfiguration))
            {
                std::cerr << "error setting json file\n";
                throw DBusInternalError();
            }
        });
}

static bool checkArrayElementsSameType(nlohmann::json& value)
{
    nlohmann::json::array_t* arr = value.get_ptr<nlohmann::json::array_t*>();
    if (arr == nullptr)
    {
        return false;
    }

    if (arr->empty())
    {
        return true;
    }

    nlohmann::json::value_t firstType = value[0].type();
    return std::ranges::all_of(value, [firstType](const nlohmann::json& el) {
        return el.type() == firstType;
    });
}

static nlohmann::json::value_t getDBusType(
    const nlohmann::json& value, nlohmann::json::value_t type,
    sdbusplus::asio::PropertyPermission permission)
{
    const bool array = value.type() == nlohmann::json::value_t::array;

    if (permission == sdbusplus::asio::PropertyPermission::readWrite)
    {
        // all setable numbers are doubles as it is difficult to always
        // create a configuration file with all whole numbers as decimals
        // i.e. 1.0
        if (array)
        {
            if (value[0].is_number())
            {
                return nlohmann::json::value_t::number_float;
            }
        }
        else if (value.is_number())
        {
            return nlohmann::json::value_t::number_float;
        }
    }

    return type;
}

static void populateInterfacePropertyFromJson(
    nlohmann::json& systemConfiguration, const std::string& path,
    const nlohmann::json& key, const nlohmann::json& value,
    nlohmann::json::value_t type,
    std::shared_ptr<sdbusplus::asio::dbus_interface>& iface,
    sdbusplus::asio::PropertyPermission permission)
{
    const auto modifiedType = getDBusType(value, type, permission);

    switch (modifiedType)
    {
        case (nlohmann::json::value_t::boolean):
        {
            // todo: array of bool isn't detected correctly by
            // sdbusplus, change it to numbers
            addValueToDBus<uint64_t, bool>(key, value, *iface, permission,
                                           systemConfiguration, path);
            break;
        }
        case (nlohmann::json::value_t::number_integer):
        {
            addValueToDBus<int64_t>(key, value, *iface, permission,
                                    systemConfiguration, path);
            break;
        }
        case (nlohmann::json::value_t::number_unsigned):
        {
            addValueToDBus<uint64_t>(key, value, *iface, permission,
                                     systemConfiguration, path);
            break;
        }
        case (nlohmann::json::value_t::number_float):
        {
            addValueToDBus<double>(key, value, *iface, permission,
                                   systemConfiguration, path);
            break;
        }
        case (nlohmann::json::value_t::string):
        {
            addValueToDBus<std::string>(key, value, *iface, permission,
                                        systemConfiguration, path);
            break;
        }
        default:
        {
            std::cerr << "Unexpected json type in system configuration " << key
                      << ": " << value.type_name() << "\n";
            break;
        }
    }
}

// adds simple json types to interface's properties
void populateInterfaceFromJson(
    boost::asio::io_context& io, nlohmann::json& systemConfiguration,
    const std::string& jsonPointerPath,
    std::shared_ptr<sdbusplus::asio::dbus_interface>& iface,
    nlohmann::json& dict, sdbusplus::asio::object_server& objServer,
    sdbusplus::asio::PropertyPermission permission)
{
    for (const auto& [key, value] : dict.items())
    {
        auto type = value.type();
        if (value.type() == nlohmann::json::value_t::array)
        {
            if (value.empty())
            {
                continue;
            }
            type = value[0].type();
            if (!checkArrayElementsSameType(value))
            {
                std::cerr << "dbus format error" << value << "\n";
                continue;
            }
        }
        if (type == nlohmann::json::value_t::object)
        {
            continue; // handled elsewhere
        }

        std::string path = jsonPointerPath;
        path.append("/").append(key);

        populateInterfacePropertyFromJson(systemConfiguration, path, key, value,
                                          type, iface, permission);
    }
    if (permission == sdbusplus::asio::PropertyPermission::readWrite)
    {
        createDeleteObjectMethod(jsonPointerPath, iface, objServer,
                                 systemConfiguration, io);
    }
    tryIfaceInitialize(iface);
}

void createAddObjectMethod(
    boost::asio::io_context& io, const std::string& jsonPointerPath,
    const std::string& path, nlohmann::json& systemConfiguration,
    sdbusplus::asio::object_server& objServer, const std::string& board)
{
    std::shared_ptr<sdbusplus::asio::dbus_interface> iface = createInterface(
        objServer, path, "xyz.openbmc_project.AddObject", board);

    iface->register_method(
        "AddObject",
        [&systemConfiguration, &objServer,
         jsonPointerPath{std::string(jsonPointerPath)}, path{std::string(path)},
         board,
         &io](const boost::container::flat_map<std::string, JsonVariantType>&
                  data) {
            nlohmann::json::json_pointer ptr(jsonPointerPath);
            nlohmann::json& base = systemConfiguration[ptr];
            auto findExposes = base.find("Exposes");

            if (findExposes == base.end())
            {
                throw std::invalid_argument("Entity must have children.");
            }

            // this will throw invalid-argument to sdbusplus if invalid json
            nlohmann::json newData{};
            for (const auto& item : data)
            {
                nlohmann::json& newJson = newData[item.first];
                std::visit(
                    [&newJson](auto&& val) {
                        newJson = std::forward<decltype(val)>(val);
                    },
                    item.second);
            }

            auto findName = newData.find("Name");
            auto findType = newData.find("Type");
            if (findName == newData.end() || findType == newData.end())
            {
                throw std::invalid_argument("AddObject missing Name or Type");
            }
            const std::string* type = findType->get_ptr<const std::string*>();
            const std::string* name = findName->get_ptr<const std::string*>();
            if (type == nullptr || name == nullptr)
            {
                throw std::invalid_argument("Type and Name must be a string.");
            }

            bool foundNull = false;
            size_t lastIndex = 0;
            // we add in the "exposes"
            for (const auto& expose : *findExposes)
            {
                if (expose.is_null())
                {
                    foundNull = true;
                    continue;
                }

                if (expose["Name"] == *name && expose["Type"] == *type)
                {
                    throw std::invalid_argument(
                        "Field already in JSON, not adding");
                }

                if (foundNull)
                {
                    continue;
                }

                lastIndex++;
            }

            std::ifstream schemaFile(
                std::string(configuration::schemaDirectory) + "/" +
                boost::to_lower_copy(*type) + ".json");
            // todo(james) we might want to also make a list of 'can add'
            // interfaces but for now I think the assumption if there is a
            // schema avaliable that it is allowed to update is fine
            if (!schemaFile.good())
            {
                throw std::invalid_argument(
                    "No schema avaliable, cannot validate.");
            }
            nlohmann::json schema =
                nlohmann::json::parse(schemaFile, nullptr, false, true);
            if (schema.is_discarded())
            {
                std::cerr << "Schema not legal" << *type << ".json\n";
                throw DBusInternalError();
            }
            if (!configuration::validateJson(schema, newData))
            {
                throw std::invalid_argument("Data does not match schema");
            }
            if (foundNull)
            {
                findExposes->at(lastIndex) = newData;
            }
            else
            {
                findExposes->push_back(newData);
            }
            if (!configuration::writeJsonFiles(systemConfiguration))
            {
                std::cerr << "Error writing json files\n";
                throw DBusInternalError();
            }
            std::string dbusName = *name;

            std::regex_replace(dbusName.begin(), dbusName.begin(),
                               dbusName.end(), illegalDbusMemberRegex, "_");

            std::shared_ptr<sdbusplus::asio::dbus_interface> interface =
                createInterface(objServer, path + "/" + dbusName,
                                "xyz.openbmc_project.Configuration." + *type,
                                board, true);
            // permission is read-write, as since we just created it, must be
            // runtime modifiable
            populateInterfaceFromJson(
                io, systemConfiguration,
                jsonPointerPath + "/Exposes/" + std::to_string(lastIndex),
                interface, newData, objServer,
                sdbusplus::asio::PropertyPermission::readWrite);
        });
    tryIfaceInitialize(iface);
}

std::vector<std::weak_ptr<sdbusplus::asio::dbus_interface>>&
    getDeviceInterfaces(const nlohmann::json& device)
{
    return inventory[device["Name"].get<std::string>()];
}

} // namespace dbus_interface
