#include "association_manager.hpp"

#include <phosphor-logging/log.hpp>

#include <filesystem>
#include <fstream>

namespace phosphor
{
namespace inventory
{
namespace manager
{
namespace associations
{
using namespace phosphor::logging;
namespace fs = std::filesystem;

Manager::Manager(sdbusplus::bus::bus& bus, const std::string& jsonPath) :
    _bus(bus), _jsonFile(jsonPath)
{
    // If there aren't any conditional associations files, look for
    // that default nonconditional one.
    if (!loadConditions())
    {
        if (fs::exists(_jsonFile))
        {
            std::ifstream file{_jsonFile};
            auto json = nlohmann::json::parse(file, nullptr, true);
            load(json);
        }
    }
}

/**
 * @brief Throws an exception if 'num' is zero. Used for JSON
 *        sanity checking.
 *
 * @param[in] num - the number to check
 */
void throwIfZero(int num)
{
    if (!num)
    {
        throw std::invalid_argument("Invalid empty field in JSON");
    }
}

bool Manager::loadConditions()
{
    auto dir = _jsonFile.parent_path();

    for (const auto& dirent : fs::recursive_directory_iterator(dir))
    {
        const auto& path = dirent.path();
        if (path.extension() == ".json")
        {
            std::ifstream file{path};
            auto json = nlohmann::json::parse(file, nullptr, true);

            if (json.is_object() && json.contains("condition"))
            {
                const auto& conditionJSON = json.at("condition");
                if (!conditionJSON.contains("path") ||
                    !conditionJSON.contains("interface") ||
                    !conditionJSON.contains("property") ||
                    !conditionJSON.contains("values"))
                {
                    std::string msg =
                        "Invalid JSON in associations condition entry in " +
                        path.string() + ". Skipping file.";
                    log<level::ERR>(msg.c_str());
                    continue;
                }

                Condition c;
                c.file = path;
                c.path = conditionJSON["path"].get<std::string>();
                if (c.path.front() != '/')
                {
                    c.path = '/' + c.path;
                }
                fprintf(stderr, "found conditions file %s\n", c.file.c_str());
                c.interface = conditionJSON["interface"].get<std::string>();
                c.property = conditionJSON["property"].get<std::string>();

                // The values are in an array, and need to be
                // converted to an InterfaceVariantType.
                for (const auto& value : conditionJSON["values"])
                {
                    if (value.is_array())
                    {
                        std::vector<uint8_t> variantValue;
                        for (const auto& v : value)
                        {
                            variantValue.push_back(v.get<uint8_t>());
                        }
                        c.values.push_back(variantValue);
                        continue;
                    }

                    // Try the remaining types
                    auto s = value.get_ptr<const std::string*>();
                    auto i = value.get_ptr<const int64_t*>();
                    auto b = value.get_ptr<const bool*>();
                    if (s)
                    {
                        c.values.push_back(*s);
                    }
                    else if (i)
                    {
                        c.values.push_back(*i);
                    }
                    else if (b)
                    {
                        c.values.push_back(*b);
                    }
                    else
                    {
                        std::stringstream ss;
                        ss << "Invalid condition property value in " << c.file
                           << ": " << value;
                        log<level::ERR>(ss.str().c_str());
                        throw std::runtime_error(ss.str());
                    }
                }

                _conditions.push_back(std::move(c));
            }
        }
    }

    return !_conditions.empty();
}

bool Manager::conditionMatch(const sdbusplus::message::object_path& objectPath,
                             const Object& object)
{
    fs::path foundPath;
    for (const auto& condition : _conditions)
    {
        if (condition.path != objectPath)
        {
            continue;
        }

        auto interface = std::find_if(object.begin(), object.end(),
                                      [&condition](const auto& i) {
                                          return i.first == condition.interface;
                                      });
        if (interface == object.end())
        {
            continue;
        }

        auto property =
            std::find_if(interface->second.begin(), interface->second.end(),
                         [&condition](const auto& p) {
                             return condition.property == p.first;
                         });
        if (property == interface->second.end())
        {
            continue;
        }

        auto match = std::find(condition.values.begin(), condition.values.end(),
                               property->second);
        if (match != condition.values.end())
        {
            foundPath = condition.file;
            break;
        }
    }

    if (!foundPath.empty())
    {
        std::ifstream file{foundPath};
        auto json = nlohmann::json::parse(file, nullptr, true);
        load(json["associations"]);
        _conditions.clear();
        return true;
    }

    return false;
}

bool Manager::conditionMatch()
{
    fs::path foundPath;

    for (const auto& condition : _conditions)
    {
        // Compare the actualValue field against the values in the
        // values vector to see if there is a condition match.
        auto found = std::find(condition.values.begin(), condition.values.end(),
                               condition.actualValue);
        if (found != condition.values.end())
        {
            foundPath = condition.file;
            break;
        }
    }

    if (!foundPath.empty())
    {
        std::ifstream file{foundPath};
        auto json = nlohmann::json::parse(file, nullptr, true);
        load(json["associations"]);
        _conditions.clear();
        return true;
    }

    return false;
}

void Manager::load(const nlohmann::json& json)
{
    const std::string root{INVENTORY_ROOT};

    for (const auto& jsonAssoc : json)
    {
        // Only add the slash if necessary
        std::string path = jsonAssoc.at("path");
        throwIfZero(path.size());
        if (path.front() != '/')
        {
            path = root + "/" + path;
        }
        else
        {
            path = root + path;
        }

        auto& assocEndpoints = _associations[path];

        for (const auto& endpoint : jsonAssoc.at("endpoints"))
        {
            std::string ftype = endpoint.at("types").at("fType");
            std::string rtype = endpoint.at("types").at("rType");
            throwIfZero(ftype.size());
            throwIfZero(rtype.size());
            Types types{std::move(ftype), std::move(rtype)};

            Paths paths = endpoint.at("paths");
            throwIfZero(paths.size());
            assocEndpoints.emplace_back(std::move(types), std::move(paths));
        }
    }
}

void Manager::createAssociations(const std::string& objectPath,
                                 bool deferSignal)
{
    auto endpoints = _associations.find(objectPath);
    if (endpoints == _associations.end())
    {
        return;
    }

    if (std::find(_handled.begin(), _handled.end(), objectPath) !=
        _handled.end())
    {
        return;
    }

    _handled.push_back(objectPath);

    for (const auto& endpoint : endpoints->second)
    {
        const auto& types = std::get<typesPos>(endpoint);
        const auto& paths = std::get<pathsPos>(endpoint);

        for (const auto& endpointPath : paths)
        {
            const auto& forwardType = std::get<forwardTypePos>(types);
            const auto& reverseType = std::get<reverseTypePos>(types);

            createAssociation(objectPath, forwardType, endpointPath,
                              reverseType, deferSignal);
        }
    }
}

void Manager::createAssociation(const std::string& forwardPath,
                                const std::string& forwardType,
                                const std::string& reversePath,
                                const std::string& reverseType,
                                bool deferSignal)
{
    auto object = _associationIfaces.find(forwardPath);
    if (object == _associationIfaces.end())
    {
        auto a = std::make_unique<AssociationObject>(_bus, forwardPath.c_str(),
                                                     true);

        using AssociationProperty =
            std::vector<std::tuple<std::string, std::string, std::string>>;
        AssociationProperty prop;

        prop.emplace_back(forwardType, reverseType, reversePath);
        a->associations(std::move(prop));
        if (!deferSignal)
        {
            a->emit_object_added();
        }
        _associationIfaces.emplace(forwardPath, std::move(a));
    }
    else
    {
        // Interface exists, just update the property
        auto prop = object->second->associations();
        prop.emplace_back(forwardType, reverseType, reversePath);
        object->second->associations(std::move(prop), deferSignal);
    }
}
} // namespace associations
} // namespace manager
} // namespace inventory
} // namespace phosphor
