#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
{
  public:
    boost::asio::io_context io;
    virtual void SetUp()
    {
        io.run();
    }
};
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(io, sourcePath, defaultDbusSvc, *server, assocMaps);
}

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

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

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

    assocMaps.owners = createDefaultOwnerAssociation();

    removeAssociation(io, 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(io, 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(io, 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(io, 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(io, 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(io, 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(io, *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(io, *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(io, *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(io, *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(io, *server, associations, defaultSourcePath,
                       defaultDbusSvc, interfaceMap, assocMaps);

    // Should have 2 entries in AssociationInterfaces
    // The one missing an endpoint is not added.
    EXPECT_EQ(assocMaps.ifaces.size(), 2);

    // 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(io, *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", defaultDbusSvc,
                                  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, defaultDbusSvc, assocMaps);
    EXPECT_EQ(assocMaps.pending.size(), 0);
}

// Test removing pending associations by multiple owners
TEST_F(TestAssociations, testRemoveFromPendingAssociationsMultipleOwners)
{
    AssociationMaps assocMaps;

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

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

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

    removeFromPendingAssociations(defaultEndpoint, "serviceB", 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(), 1);
    EXPECT_EQ(std::get<ownerPos>(endpoints[0]), "serviceA");
}

// 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(io, 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(io, "/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(io, 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(io, 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());
    }
}
