#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;
using sdbusplus::exception::SdBusError;
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
