#include "dbus_interface.hpp"

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

#include <boost/container/flat_map.hpp>
#include <phosphor-logging/lg2.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_]");

EMDBusInterface::EMDBusInterface(boost::asio::io_context& io,
                                 sdbusplus::asio::object_server& objServer) :
    io(io), objServer(objServer)
{}

void tryIfaceInitialize(std::shared_ptr<sdbusplus::asio::dbus_interface>& iface)
{
    try
    {
        iface->initialize();
    }
    catch (std::exception& e)
    {
        lg2::error(
            "Unable to initialize dbus interface : {ERR} object Path : {PATH} interface name : {INTF}",
            "ERR", e, "PATH", iface->get_object_path(), "INTF",
            iface->get_interface_name());
    }
}

std::shared_ptr<sdbusplus::asio::dbus_interface>
    EMDBusInterface::createInterface(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 EMDBusInterface::createDeleteObjectMethod(
    const std::string& jsonPointerPath,
    const std::shared_ptr<sdbusplus::asio::dbus_interface>& iface,
    nlohmann::json& systemConfiguration)
{
    std::weak_ptr<sdbusplus::asio::dbus_interface> interface = iface;
    iface->register_method(
        "Delete", [this, &systemConfiguration, interface,
                   jsonPointerPath{std::string(jsonPointerPath)}]() {
            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, [dbusInterface, this]() mutable {
                objServer.remove_interface(dbusInterface);
            });

            if (!writeJsonFiles(systemConfiguration))
            {
                lg2::error("error setting json file");
                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):
        {
            addValueToDBus<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:
        {
            lg2::error(
                "Unexpected json type in system configuration {KEY}: {VALUE}",
                "KEY", key, "VALUE", value.type_name());
            break;
        }
    }
}

// adds simple json types to interface's properties
void EMDBusInterface::populateInterfaceFromJson(
    nlohmann::json& systemConfiguration, const std::string& jsonPointerPath,
    std::shared_ptr<sdbusplus::asio::dbus_interface>& iface,
    nlohmann::json& dict, 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))
            {
                lg2::error("dbus format error {VALUE}", "VALUE", value);
                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, systemConfiguration);
    }
    tryIfaceInitialize(iface);
}

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

    iface->register_method(
        "AddObject",
        [&systemConfiguration, jsonPointerPath{std::string(jsonPointerPath)},
         path{std::string(path)}, board,
         this](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++;
            }

            if constexpr (ENABLE_RUNTIME_VALIDATE_JSON)
            {
                const std::filesystem::path schemaPath =
                    std::filesystem::path(schemaDirectory) /
                    "exposes_record.json";

                std::ifstream schemaFile{schemaPath};

                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())
                {
                    lg2::error("Schema not legal: {TYPE}.json", "TYPE", *type);
                    throw DBusInternalError();
                }

                if (!validateJson(schema, newData))
                {
                    throw std::invalid_argument("Data does not match schema");
                }
            }

            if (foundNull)
            {
                findExposes->at(lastIndex) = newData;
            }
            else
            {
                findExposes->push_back(newData);
            }
            if (!writeJsonFiles(systemConfiguration))
            {
                lg2::error("Error writing json files");
            }
            std::string dbusName = *name;

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

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

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

} // namespace dbus_interface
