#include "src/associations.hpp"

#include "src/test/util/asio_server_class.hpp"
#include "src/test/util/association_objects.hpp"
#include "src/test/util/debug_output.hpp"

#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/asio/object_server.hpp>

#include <gtest/gtest.h>

class TestAssociations : public AsioServerClassTest
{};
sdbusplus::asio::object_server* TestAssociations::AsioServerClassTest::server =
    nullptr;

// Verify call when path is not in associated owners
TEST_F(TestAssociations, SourcePathNotInAssociations)
{
    EXPECT_NE(nullptr, server);
    std::string sourcePath = "/xyz/openbmc_project/no/association";
    AssociationMaps assocMaps;

    removeAssociation(sourcePath, defaultDbusSvc, *server, assocMaps);
}

// Verify call when owner is not in associated owners
TEST_F(TestAssociations, OwnerNotInAssociations)
{
    AssociationMaps assocMaps;
    assocMaps.owners = createDefaultOwnerAssociation();

    removeAssociation(defaultSourcePath, defaultDbusSvc, *server, assocMaps);
}

// Verify call when path is not in associated interfaces
TEST_F(TestAssociations, PathNotInAssocInterfaces)
{
    AssociationMaps assocMaps;

    assocMaps.owners = createDefaultOwnerAssociation();

    removeAssociation(defaultSourcePath, defaultDbusSvc, *server, assocMaps);

    EXPECT_TRUE(assocMaps.owners.empty());
}

// Verify call when path is in associated interfaces
TEST_F(TestAssociations, PathIsInAssociatedInterfaces)
{
    // Build up these objects so that an associated interface will match
    // with the associated owner being removed
    AssociationMaps assocMaps;
    assocMaps.owners = createDefaultOwnerAssociation();
    assocMaps.ifaces = createDefaultInterfaceAssociation(server);

    removeAssociation(defaultSourcePath, defaultDbusSvc, *server, assocMaps);

    // Verify owner association was deleted
    EXPECT_TRUE(assocMaps.owners.empty());

    // Verify endpoint was deleted from interface association
    auto intfEndpoints =
        std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
    EXPECT_EQ(intfEndpoints.size(), 0);
    intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[defaultRevPath]);
    EXPECT_EQ(intfEndpoints.size(), 0);
}

// Verify call when path is in associated interfaces, with extra endpoints
TEST_F(TestAssociations, PathIsInAssociatedInterfacesExtraEndpoints)
{
    // Build up these objects so that an associated interface will match
    // with the associated owner being removed
    AssociationMaps assocMaps;
    assocMaps.owners = createDefaultOwnerAssociation();
    assocMaps.ifaces = createDefaultInterfaceAssociation(server);

    // Add another endpoint to the assoc interfaces
    addEndpointToInterfaceAssociation(assocMaps.ifaces);

    removeAssociation(defaultSourcePath, defaultDbusSvc, *server, assocMaps);

    // Verify owner association was deleted
    EXPECT_TRUE(assocMaps.owners.empty());

    // Verify all endpoints are deleted since source path was deleted
    auto intfEndpoints =
        std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
    EXPECT_EQ(intfEndpoints.size(), 0);
    intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[defaultRevPath]);
    EXPECT_EQ(intfEndpoints.size(), 0);
}

// Verify no associations or endpoints removed when the change is identical
TEST_F(TestAssociations, checkAssociationEndpointRemovesNoEpRemove)
{
    AssociationPaths newAssocPaths = {{defaultFwdPath, {defaultEndpoint}},
                                      {defaultRevPath, {defaultSourcePath}}};

    AssociationMaps assocMaps;
    assocMaps.owners = createDefaultOwnerAssociation();
    assocMaps.ifaces = createDefaultInterfaceAssociation(server);

    checkAssociationEndpointRemoves(defaultSourcePath, defaultDbusSvc,
                                    newAssocPaths, *server, assocMaps);

    // Verify endpoints were not deleted because they matche with what was
    // in the original
    auto intfEndpoints =
        std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
    EXPECT_EQ(intfEndpoints.size(), 1);
    intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[defaultRevPath]);
    EXPECT_EQ(intfEndpoints.size(), 1);
}

// Verify endpoint is removed when assoc path is different
TEST_F(TestAssociations, checkAssociationEndpointRemovesEpRemoveApDiff)
{
    AssociationPaths newAssocPaths = {{"/different/path", {defaultEndpoint}}};

    AssociationMaps assocMaps;
    assocMaps.owners = createDefaultOwnerAssociation();
    assocMaps.ifaces = createDefaultInterfaceAssociation(server);

    checkAssociationEndpointRemoves(defaultSourcePath, defaultDbusSvc,
                                    newAssocPaths, *server, assocMaps);

    // Verify initial endpoints were deleted because the new path
    auto intfEndpoints =
        std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
    EXPECT_EQ(intfEndpoints.size(), 0);
    intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[defaultRevPath]);
    EXPECT_EQ(intfEndpoints.size(), 0);
}

// Verify endpoint is removed when endpoint is different
TEST_F(TestAssociations, checkAssociationEndpointRemovesEpRemoveEpChanged)
{
    AssociationPaths newAssocPaths = {
        {defaultFwdPath, {defaultEndpoint + "/different"}},
        {defaultRevPath, {defaultSourcePath + "/different"}}};

    AssociationMaps assocMaps;
    assocMaps.owners = createDefaultOwnerAssociation();
    assocMaps.ifaces = createDefaultInterfaceAssociation(server);

    checkAssociationEndpointRemoves(defaultSourcePath, defaultDbusSvc,
                                    newAssocPaths, *server, assocMaps);

    // Verify initial endpoints were deleted because of different endpoints
    auto intfEndpoints =
        std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
    EXPECT_EQ(intfEndpoints.size(), 0);
    intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[defaultRevPath]);
    EXPECT_EQ(intfEndpoints.size(), 0);
}

// Verify existing endpoint deleted when empty endpoint is provided
TEST_F(TestAssociations, associationChangedEmptyEndpoint)
{
    std::vector<Association> associations = {
        {"inventory_cee", "error_cee", ""}};
    InterfaceMapType interfaceMap;

    AssociationMaps assocMaps;
    assocMaps.owners = createDefaultOwnerAssociation();
    assocMaps.ifaces = createDefaultInterfaceAssociation(server);

    // Empty endpoint will result in deletion of corresponding assocInterface
    associationChanged(*server, associations, defaultSourcePath, defaultDbusSvc,
                       interfaceMap, assocMaps);

    // Both of these should be 0 since we have an invalid endpoint
    auto intfEndpoints =
        std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
    EXPECT_EQ(intfEndpoints.size(), 0);
    intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[defaultRevPath]);
    EXPECT_EQ(intfEndpoints.size(), 0);

    EXPECT_EQ(assocMaps.pending.size(), 0);
}

// Add a new association with endpoint
TEST_F(TestAssociations, associationChangedAddNewAssoc)
{
    std::vector<Association> associations = {
        {"abc", "def", "/xyz/openbmc_project/new/endpoint"}};

    AssociationMaps assocMaps;
    assocMaps.owners = createDefaultOwnerAssociation();
    assocMaps.ifaces = createDefaultInterfaceAssociation(server);

    // Make it look like the assoc endpoints are on D-Bus
    InterfaceMapType interfaceMap = {
        {"/new/source/path", {{defaultDbusSvc, {"a"}}}},
        {"/xyz/openbmc_project/new/endpoint", {{defaultDbusSvc, {"a"}}}}};

    associationChanged(*server, associations, "/new/source/path",
                       defaultDbusSvc, interfaceMap, assocMaps);

    // Two source paths
    EXPECT_EQ(assocMaps.owners.size(), 2);

    // Four interfaces
    EXPECT_EQ(assocMaps.ifaces.size(), 4);

    // Nothing pending
    EXPECT_EQ(assocMaps.pending.size(), 0);

    // New endpoint so assocMaps.ifaces should be same size
    auto intfEndpoints =
        std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
    EXPECT_EQ(intfEndpoints.size(), 1);
}

// Add a new association to empty objects
TEST_F(TestAssociations, associationChangedAddNewAssocEmptyObj)
{
    std::string sourcePath = "/logging/entry/1";
    std::string owner = "xyz.openbmc_project.Test";
    std::vector<Association> associations = {
        {"inventory_canaeo", "error_canaeo",
         "/xyz/openbmc_project/inventory/system/chassis"}};

    // Empty objects because this test will ensure assocOwners adds the
    // changed association and interface
    AssociationMaps assocMaps;

    // Make it look like the assoc endpoints are on D-Bus
    InterfaceMapType interfaceMap = createDefaultInterfaceMap();

    associationChanged(*server, associations, defaultSourcePath, defaultDbusSvc,
                       interfaceMap, assocMaps);

    // New associations so ensure it now contains a single entry
    EXPECT_EQ(assocMaps.owners.size(), 1);

    // Nothing pending
    EXPECT_EQ(assocMaps.pending.size(), 0);

    // Verify corresponding assoc paths each have one endpoint in assoc
    // interfaces and that those endpoints match
    auto singleOwner = assocMaps.owners[defaultSourcePath];
    auto singleIntf = singleOwner[defaultDbusSvc];
    for (auto i : singleIntf)
    {
        auto intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[i.first]);
        EXPECT_EQ(intfEndpoints.size(), 1);
        EXPECT_EQ(intfEndpoints[0], *i.second.begin());
    }
}

// Add a new association to same source path but with new owner
TEST_F(TestAssociations, associationChangedAddNewAssocNewOwner)
{
    std::string newOwner = "xyz.openbmc_project.Test2";
    std::vector<Association> associations = {
        {"inventory_canano", "error_canano",
         "/xyz/openbmc_project/inventory/system/chassis"}};

    // Make it look like the assoc endpoints are on D-Bus
    InterfaceMapType interfaceMap = createDefaultInterfaceMap();

    AssociationMaps assocMaps;
    assocMaps.owners = createDefaultOwnerAssociation();
    assocMaps.ifaces = createDefaultInterfaceAssociation(server);

    associationChanged(*server, associations, defaultSourcePath, newOwner,
                       interfaceMap, assocMaps);

    // New endpoint so assocOwners should be same size
    EXPECT_EQ(assocMaps.owners.size(), 1);

    // Ensure only one endpoint under first path
    auto intfEndpoints =
        std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
    EXPECT_EQ(intfEndpoints.size(), 1);

    // Ensure the 2 new association endpoints are under the new owner
    auto a = assocMaps.owners.find(defaultSourcePath);
    auto o = a->second.find(newOwner);
    EXPECT_EQ(o->second.size(), 2);

    // Nothing pending
    EXPECT_EQ(assocMaps.pending.size(), 0);
}

// Add a new association to existing interface path
TEST_F(TestAssociations, associationChangedAddNewAssocSameInterface)
{
    std::vector<Association> associations = {
        {"abc", "error", "/xyz/openbmc_project/inventory/system/chassis"}};

    // Make it look like the assoc endpoints are on D-Bus
    InterfaceMapType interfaceMap = createDefaultInterfaceMap();

    AssociationMaps assocMaps;
    assocMaps.owners = createDefaultOwnerAssociation();
    assocMaps.ifaces = createDefaultInterfaceAssociation(server);

    associationChanged(*server, associations, defaultSourcePath, defaultDbusSvc,
                       interfaceMap, assocMaps);

    // Should have 3 entries in AssociationInterfaces, one is just missing an
    // endpoint
    EXPECT_EQ(assocMaps.ifaces.size(), 3);

    // Change to existing interface so it will be removed here
    auto intfEndpoints =
        std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
    EXPECT_EQ(intfEndpoints.size(), 0);

    // The new endpoint should exist though in it's place
    intfEndpoints = std::get<endpointsPos>(
        assocMaps.ifaces[defaultSourcePath + "/" + "abc"]);
    EXPECT_EQ(intfEndpoints.size(), 1);

    // Added to an existing owner path so still 1
    EXPECT_EQ(assocMaps.owners.size(), 1);

    EXPECT_EQ(assocMaps.pending.size(), 0);
}

// Add 2 pending associations
TEST_F(TestAssociations, addPendingAssocs)
{
    AssociationMaps assocMaps;

    addPendingAssociation(defaultSourcePath, "inventory", defaultEndpoint,
                          "error", defaultDbusSvc, assocMaps);

    EXPECT_TRUE(assocMaps.ifaces.empty());
    EXPECT_TRUE(assocMaps.owners.empty());

    EXPECT_EQ(assocMaps.pending.size(), 1);

    addPendingAssociation("some/other/path", "inventory", defaultEndpoint,
                          "error", defaultDbusSvc, assocMaps);

    EXPECT_TRUE(assocMaps.ifaces.empty());
    EXPECT_TRUE(assocMaps.owners.empty());

    EXPECT_EQ(assocMaps.pending.size(), 2);
}

// Test adding a new endpoint to a pending association
TEST_F(TestAssociations, addPendingAssocsNewEndpoints)
{
    AssociationMaps assocMaps;

    addPendingAssociation(defaultSourcePath, "inventory", defaultEndpoint,
                          "error", defaultDbusSvc, assocMaps);

    EXPECT_EQ(assocMaps.pending.size(), 1);

    addPendingAssociation(defaultSourcePath, "inventory", "some/other/endpoint",
                          "error", defaultDbusSvc, assocMaps);

    // Same pending path, so still just 1 entry
    EXPECT_EQ(assocMaps.pending.size(), 1);

    auto assoc = assocMaps.pending.find(defaultSourcePath);
    EXPECT_NE(assoc, assocMaps.pending.end());

    auto& endpoints = assoc->second;
    EXPECT_EQ(endpoints.size(), 2);
}

// Test adding a new owner to a pending association
TEST_F(TestAssociations, addPendingAssocsNewOwner)
{
    AssociationMaps assocMaps;

    addPendingAssociation(defaultSourcePath, "inventory", defaultEndpoint,
                          "error", defaultDbusSvc, assocMaps);

    EXPECT_EQ(assocMaps.pending.size(), 1);

    addPendingAssociation(defaultSourcePath, "inventory", defaultEndpoint,
                          "error", "new owner", assocMaps);

    EXPECT_EQ(assocMaps.pending.size(), 1);

    auto assoc = assocMaps.pending.find(defaultSourcePath);
    EXPECT_NE(assoc, assocMaps.pending.end());

    auto& endpoints = assoc->second;
    EXPECT_EQ(endpoints.size(), 2);
}

// Add a pending association inside associationChanged
TEST_F(TestAssociations, associationChangedPending)
{
    std::vector<Association> associations = {
        {"abc", "def", "/xyz/openbmc_project/new/endpoint"}};

    AssociationMaps assocMaps;
    InterfaceMapType interfaceMap;

    associationChanged(*server, associations, "/new/source/path",
                       defaultDbusSvc, interfaceMap, assocMaps);

    // No associations were actually added
    EXPECT_EQ(assocMaps.owners.size(), 0);
    EXPECT_EQ(assocMaps.ifaces.size(), 0);

    // 1 pending association
    EXPECT_EQ(assocMaps.pending.size(), 1);
}

// Test removing pending associations
TEST_F(TestAssociations, testRemoveFromPendingAssociations)
{
    AssociationMaps assocMaps;

    addPendingAssociation(defaultSourcePath, "inventory", defaultEndpoint,
                          "error", defaultDbusSvc, assocMaps);

    addPendingAssociation(defaultSourcePath, "inventory", "some/other/endpoint",
                          "error", defaultDbusSvc, assocMaps);

    EXPECT_EQ(assocMaps.pending.size(), 1);

    removeFromPendingAssociations("some/other/endpoint", assocMaps);

    // Still 1 pending entry, but down to 1 endpoint
    EXPECT_EQ(assocMaps.pending.size(), 1);

    auto assoc = assocMaps.pending.find(defaultSourcePath);
    EXPECT_NE(assoc, assocMaps.pending.end());
    auto& endpoints = assoc->second;
    EXPECT_EQ(endpoints.size(), 1);

    // Now nothing pending
    removeFromPendingAssociations(defaultEndpoint, assocMaps);
    EXPECT_EQ(assocMaps.pending.size(), 0);
}

// Test moving a pending association to a real one
TEST_F(TestAssociations, checkIfPending)
{
    AssociationMaps assocMaps;
    InterfaceMapType interfaceMap = {
        {defaultSourcePath, {{defaultDbusSvc, {"a"}}}},
        {defaultEndpoint, {{defaultDbusSvc, {"b"}}}}};

    addPendingAssociation(defaultSourcePath, "inventory_cip", defaultEndpoint,
                          "error_cip", defaultDbusSvc, assocMaps);
    EXPECT_EQ(assocMaps.pending.size(), 1);

    // Move the pending association to a real association
    checkIfPendingAssociation(defaultSourcePath, interfaceMap, assocMaps,
                              *server);

    EXPECT_TRUE(assocMaps.pending.empty());
    EXPECT_EQ(assocMaps.owners.size(), 1);
    EXPECT_EQ(assocMaps.ifaces.size(), 2);

    // This shouldn't do anything, since /new/path isn't pending
    checkIfPendingAssociation("/new/path", interfaceMap, assocMaps, *server);
    EXPECT_TRUE(assocMaps.pending.empty());
    EXPECT_EQ(assocMaps.owners.size(), 1);
    EXPECT_EQ(assocMaps.ifaces.size(), 2);
}

TEST_F(TestAssociations, findAssociations)
{
    std::vector<std::tuple<std::string, Association>> associationData;
    AssociationMaps assocMaps;

    assocMaps.owners = {
        {"pathA",
         {{"ownerA",
           {{"pathA/typeA", {"endpointA", "endpointB"}},
            {"endpointA/type0", {"pathA"}}}}}},

        {"pathJ",
         {{"ownerC",
           {{"pathJ/typeA", {"endpointF"}}, {"endpointF/type0", {"pathJ"}}}}}},

        {"pathX",
         {{"ownerB",
           {{"pathX/typeB", {"endpointA"}}, {"endpointA/type1", {"pathX"}}}}}}};

    findAssociations("endpointA", assocMaps, associationData);
    ASSERT_EQ(associationData.size(), 2);

    {
        auto ad = std::find_if(
            associationData.begin(), associationData.end(),
            [](const auto& ad) { return std::get<0>(ad) == "ownerA"; });
        ASSERT_NE(ad, associationData.end());

        auto& a = std::get<1>(*ad);
        ASSERT_EQ(std::get<0>(a), "type0");
        ASSERT_EQ(std::get<1>(a), "typeA");
        ASSERT_EQ(std::get<2>(a), "pathA");
    }
    {
        auto ad = std::find_if(
            associationData.begin(), associationData.end(),
            [](const auto& ad) { return std::get<0>(ad) == "ownerB"; });
        ASSERT_NE(ad, associationData.end());

        auto& a = std::get<1>(*ad);
        ASSERT_EQ(std::get<0>(a), "type1");
        ASSERT_EQ(std::get<1>(a), "typeB");
        ASSERT_EQ(std::get<2>(a), "pathX");
    }
}

TEST_F(TestAssociations, moveAssocToPendingNoOp)
{
    AssociationMaps assocMaps;

    // Not an association, so it shouldn't do anything
    moveAssociationToPending(defaultEndpoint, assocMaps, *server);

    EXPECT_TRUE(assocMaps.pending.empty());
    EXPECT_TRUE(assocMaps.owners.empty());
    EXPECT_TRUE(assocMaps.ifaces.empty());
}

TEST_F(TestAssociations, moveAssocToPending)
{
    AssociationMaps assocMaps;
    assocMaps.owners = createDefaultOwnerAssociation();
    assocMaps.ifaces = createDefaultInterfaceAssociation(server);

    moveAssociationToPending(defaultEndpoint, assocMaps, *server);

    // Check it's now pending
    EXPECT_EQ(assocMaps.pending.size(), 1);
    EXPECT_EQ(assocMaps.pending.begin()->first, defaultEndpoint);

    // No more assoc owners
    EXPECT_TRUE(assocMaps.owners.empty());

    // Check the association interfaces were removed
    {
        auto assocs = assocMaps.ifaces.find(defaultFwdPath);
        auto& iface = std::get<ifacePos>(assocs->second);
        auto& endpoints = std::get<endpointsPos>(assocs->second);

        EXPECT_EQ(iface.get(), nullptr);
        EXPECT_TRUE(endpoints.empty());
    }
    {
        auto assocs = assocMaps.ifaces.find(defaultRevPath);
        auto& iface = std::get<ifacePos>(assocs->second);
        auto& endpoints = std::get<endpointsPos>(assocs->second);

        EXPECT_EQ(iface.get(), nullptr);
        EXPECT_TRUE(endpoints.empty());
    }
}
