#include "processing.hpp"

#include "associations.hpp"

#include <algorithm>
#include <array>
#include <iostream>
#include <string>
#include <string_view>

bool getWellKnown(
    const boost::container::flat_map<std::string, std::string>& owners,
    const std::string& request, std::string& wellKnown)
{
    // If it's already a well known name, just return
    if (!request.starts_with(":"))
    {
        wellKnown = request;
        return true;
    }

    auto it = owners.find(request);
    if (it == owners.end())
    {
        return false;
    }
    wellKnown = it->second;
    return true;
}

bool needToIntrospect(const std::string& processName)
{
    using namespace std::string_view_literals;
    static constexpr std::array<std::string_view, 2> skipNamespaces{
        ":"sv, "org.freedesktop"sv};

    auto inSkipList = std::find_if(skipNamespaces.begin(), skipNamespaces.end(),
                                   [&processName](auto prefix) {
                                       return processName.starts_with(prefix);
                                   }) != skipNamespaces.end();
    return !(inSkipList || processName.empty());
}

void processNameChangeDelete(
    boost::asio::io_context& io,
    boost::container::flat_map<std::string, std::string>& nameOwners,
    const std::string& wellKnown, const std::string& oldOwner,
    InterfaceMapType& interfaceMap, AssociationMaps& assocMaps,
    sdbusplus::asio::object_server& server)
{
    if (oldOwner.starts_with(":"))
    {
        auto it = nameOwners.find(oldOwner);
        if (it != nameOwners.end())
        {
            nameOwners.erase(it);
        }
    }
    // Connection removed
    InterfaceMapType::iterator pathIt = interfaceMap.begin();
    while (pathIt != interfaceMap.end())
    {
        // If an associations interface is being removed,
        // also need to remove the corresponding associations
        // objects and properties.
        auto ifaces = pathIt->second.find(wellKnown);
        if (ifaces != pathIt->second.end())
        {
            auto assoc = std::find(ifaces->second.begin(), ifaces->second.end(),
                                   assocDefsInterface);
            if (assoc != ifaces->second.end())
            {
                removeAssociation(io, pathIt->first, wellKnown, server,
                                  assocMaps);
            }

            // Instead of checking if every single path is the endpoint of an
            // association that needs to be moved to pending, only check when
            // we own this path as well, which would be because of an
            // association.
            if ((pathIt->second.size() == 2) &&
                (pathIt->second.find("xyz.openbmc_project.ObjectMapper") !=
                 pathIt->second.end()))
            {
                // Remove the 2 association D-Bus paths and move the
                // association to pending.
                moveAssociationToPending(io, pathIt->first, assocMaps, server);
            }
        }
        pathIt->second.erase(wellKnown);
        if (pathIt->second.empty())
        {
            // If the last connection to the object is gone,
            // delete the top level object
            pathIt = interfaceMap.erase(pathIt);
            continue;
        }
        pathIt++;
    }
}

void processInterfaceAdded(
    boost::asio::io_context& io, InterfaceMapType& interfaceMap,
    const sdbusplus::object_path& objPath, const InterfacesAdded& intfAdded,
    const std::string& wellKnown, AssociationMaps& assocMaps,
    sdbusplus::asio::object_server& server)
{
    auto& ifaceList = interfaceMap[objPath.string()];

    for (const auto& interfacePair : intfAdded)
    {
        ifaceList[wellKnown].emplace(interfacePair.first);

        if (interfacePair.first == assocDefsInterface)
        {
            const std::variant<std::vector<Association>>* variantAssociations =
                nullptr;
            for (const auto& interface : interfacePair.second)
            {
                if (interface.first == assocDefsProperty)
                {
                    variantAssociations = &(interface.second);
                }
            }
            if (variantAssociations == nullptr)
            {
                std::cerr << "Illegal association found on " << wellKnown
                          << "\n";
                continue;
            }
            std::vector<Association> associations =
                std::get<std::vector<Association>>(*variantAssociations);
            associationChanged(io, server, associations, objPath, wellKnown,
                               interfaceMap, assocMaps);
        }
    }

    // To handle the case where an object path is being created
    // with 2 or more new path segments, check if the parent paths
    // of this path are already in the interface map, and add them
    // if they aren't with just the default freedesktop interfaces.
    // This would be done via introspection if they would have
    // already existed at startup.  While we could also introspect
    // them now to do the work, we know there aren't any other
    // interfaces or we would have gotten signals for them as well,
    // so take a shortcut to speed things up.
    //
    // This is all needed so that mapper operations can be done
    // on the new parent paths.
    using iface_map_iterator = InterfaceMapType::iterator;
    using name_map_iterator = ConnectionNames::iterator;

    auto parent = objPath;

    while (parent != "/")
    {
        parent = parent.parent_path();

        std::pair<iface_map_iterator, bool> parentEntry =
            interfaceMap.emplace(parent, ConnectionNames{});

        std::pair<name_map_iterator, bool> ifaceEntry =
            parentEntry.first->second.emplace(wellKnown, InterfaceNames{});

        if (!ifaceEntry.second)
        {
            // Entry was already there for this name so done.
            break;
        }
    }

    // The new interface might have an association pending
    checkIfPendingAssociation(io, objPath, interfaceMap, assocMaps, server);
}
