#include "MCTPReactor.hpp"

#include "MCTPDeviceRepository.hpp"
#include "MCTPEndpoint.hpp"
#include "Utils.hpp"

#include <boost/system/detail/error_code.hpp>
#include <phosphor-logging/lg2.hpp>
#include <phosphor-logging/lg2/flags.hpp>
#include <sdbusplus/message/native_types.hpp>

#include <memory>
#include <optional>
#include <string>
#include <system_error>
#include <utility>
#include <vector>

PHOSPHOR_LOG2_USING;

void MCTPReactor::untrackEndpoint(const std::shared_ptr<MCTPEndpoint>& ep)
{
    server.disassociate(MCTPDEndpoint::path(ep));
}

void MCTPReactor::trackEndpoint(const std::shared_ptr<MCTPEndpoint>& ep)
{
    info("Added MCTP endpoint to device: [ {MCTP_ENDPOINT} ]", "MCTP_ENDPOINT",
         ep->describe());

    ep->subscribe(
        // Degraded
        [](const std::shared_ptr<MCTPEndpoint>& ep) {
            debug("Endpoint entered degraded state: [ {MCTP_ENDPOINT} ]",
                  "MCTP_ENDPOINT", ep->describe());
        },
        // Available
        [](const std::shared_ptr<MCTPEndpoint>& ep) {
            debug("Endpoint entered available state: [ {MCTP_ENDPOINT} ]",
                  "MCTP_ENDPOINT", ep->describe());
        },
        // Removed
        [weak{weak_from_this()}](const std::shared_ptr<MCTPEndpoint>& ep) {
            info("Removed MCTP endpoint from device: [ {MCTP_ENDPOINT} ]",
                 "MCTP_ENDPOINT", ep->describe());
            if (auto self = weak.lock())
            {
                self->untrackEndpoint(ep);
                switch (self->states[ep->device()->id()])
                {
                    case MCTPDeviceState::Unmanaged:
                    case MCTPDeviceState::Assigning:
                    case MCTPDeviceState::Unassigned:
                        break;
                    case MCTPDeviceState::Assigned:
                        self->next(ep->device(), MCTPDeviceState::Lost);
                        break;
                    case MCTPDeviceState::Quarantine:
                        self->terminate(ep->device());
                        break;
                    case MCTPDeviceState::Lost:
                    case MCTPDeviceState::Recovering:
                        break;
                    case MCTPDeviceState::Recovered:
                        self->next(ep->device(), MCTPDeviceState::Lost);
                        break;
                    case MCTPDeviceState::Removing:
                        // If the configuration has been replaced then we've
                        // already terminated the state tracking
                        if (self->devices.contains(ep->device()))
                        {
                            self->terminate(ep->device());
                        }
                        break;
                    case MCTPDeviceState::Pending:
                        self->next(ep->device(), MCTPDeviceState::Unassigned);
                        break;
                }
            }
            else
            {
                info(
                    "The reactor object was destroyed concurrent to the removal of the remove match for the endpoint '{MCTP_ENDPOINT}'",
                    "MCTP_ENDPOINT", ep->describe());
            }
        });

    switch (states[ep->device()->id()])
    {
        case MCTPDeviceState::Unmanaged:
            return;
        case MCTPDeviceState::Assigning:
            next(ep->device(), MCTPDeviceState::Assigned);
            break;
        case MCTPDeviceState::Unassigned:
        case MCTPDeviceState::Assigned:
        case MCTPDeviceState::Quarantine:
            next(ep->device(), MCTPDeviceState::Recovered);
            break;
        case MCTPDeviceState::Lost:
            return;
        case MCTPDeviceState::Recovering:
            next(ep->device(), MCTPDeviceState::Recovered);
            break;
        case MCTPDeviceState::Recovered:
        case MCTPDeviceState::Removing:
        case MCTPDeviceState::Pending:
            return;
    }

    // Proxy-host the association back to the inventory at the same path as the
    // endpoint in mctpd.
    //
    // clang-format off
    // ```
    // # busctl call xyz.openbmc_project.ObjectMapper /xyz/openbmc_project/object_mapper xyz.openbmc_project.ObjectMapper GetAssociatedSubTree ooias /au/com/codeconstruct/mctp1/networks/1/endpoints/9/configured_by / 0 1 xyz.openbmc_project.Configuration.MCTPDevice
    // a{sa{sas}} 1 "/xyz/openbmc_project/inventory/system/nvme/NVMe_1/NVMe_1_Temp" 1 "xyz.openbmc_project.EntityManager" 1 "xyz.openbmc_project.Configuration.MCTPDevice"
    // ```
    // clang-format on
    std::optional<std::string> item = devices.inventoryFor(ep->device());
    if (!item)
    {
        error("Inventory missing for endpoint: [ {MCTP_ENDPOINT} ]",
              "MCTP_ENDPOINT", ep->describe());
        return;
    }
    std::vector<Association> associations{
        {"configured_by", "configures", *item}};
    server.associate(MCTPDEndpoint::path(ep), associations);
}

void MCTPReactor::setupEndpoint(const std::shared_ptr<MCTPDevice>& dev)
{
    debug(
        "Attempting to setup up MCTP endpoint for device at [ {MCTP_DEVICE} ]",
        "MCTP_DEVICE", dev->describe());
    dev->setup([weak{weak_from_this()}, wdev = std::weak_ptr<MCTPDevice>(dev)](
                   const std::error_code& ec,
                   const std::shared_ptr<MCTPEndpoint>& ep) mutable {
        auto self = weak.lock();
        if (!self)
        {
            info(
                "The reactor object was destroyed concurrent to the completion of the endpoint setup");
            return;
        }

        auto dev = wdev.lock();
        if (!dev)
        {
            info(
                "The device was destroyed concurrent to the completion of endpoint setup");
            return;
        }

        if (ec)
        {
            debug(
                "Setup failed for MCTP device at [ {MCTP_DEVICE} ], deferring: {ERROR_MESSAGE}",
                "MCTP_DEVICE", dev->describe(), "ERROR_MESSAGE", ec.message());

            switch (self->states[dev->id()])
            {
                case MCTPDeviceState::Unmanaged:
                    break;
                case MCTPDeviceState::Assigning:
                    self->next(dev, MCTPDeviceState::Unassigned);
                    break;
                case MCTPDeviceState::Unassigned:
                case MCTPDeviceState::Assigned:
                    break;
                case MCTPDeviceState::Quarantine:
                    self->terminate(dev);
                    break;
                case MCTPDeviceState::Lost:
                    break;
                case MCTPDeviceState::Recovering:
                    self->next(dev, MCTPDeviceState::Lost);
                    break;
                case MCTPDeviceState::Recovered:
                case MCTPDeviceState::Removing:
                case MCTPDeviceState::Pending:
                    break;
            }
            return;
        }

        try
        {
            self->trackEndpoint(ep);
        }
        catch (const MCTPException& e)
        {
            error("Failed to track endpoint '{MCTP_ENDPOINT}': {EXCEPTION}",
                  "MCTP_ENDPOINT", ep->describe(), "EXCEPTION", e);
            self->next(dev, MCTPDeviceState::Quarantine);
        }
    });
}

void MCTPReactor::tick()
{
    for (const auto& entry : devices)
    {
        switch (states[entry.second->id()])
        {
            case MCTPDeviceState::Unmanaged:
            case MCTPDeviceState::Assigning:
                break;
            case MCTPDeviceState::Unassigned:
                next(entry.second, MCTPDeviceState::Assigning);
                setupEndpoint(entry.second);
                break;
            case MCTPDeviceState::Assigned:
            case MCTPDeviceState::Quarantine:
                break;
            case MCTPDeviceState::Lost:
                next(entry.second, MCTPDeviceState::Recovering);
                setupEndpoint(entry.second);
                break;
            case MCTPDeviceState::Recovering:
            case MCTPDeviceState::Recovered:
            case MCTPDeviceState::Removing:
            case MCTPDeviceState::Pending:
                break;
        }
    }
}

void MCTPReactor::manageMCTPDevice(const std::string& path,
                                   const std::shared_ptr<MCTPDevice>& device)
{
    if (!device)
    {
        return;
    }

    debug("MCTP device inventory added at '{INVENTORY_PATH}'", "INVENTORY_PATH",
          path);

    if (!states.contains(device->id()))
    {
        debug(
            "Initialising state for device {DEVICE_ID} ([ {DEVICE_DESCRIPTION} ])) as {INITIAL_STATE}",
            "DEVICE_ID", lg2::hex, device->id(), "DEVICE_DESCRIPTION",
            device->describe(), "INITIAL_STATE", MCTPDeviceState::Unmanaged);
        states[device->id()] = MCTPDeviceState::Unmanaged;
    }

    switch (states[device->id()])
    {
        case MCTPDeviceState::Unmanaged:
            devices.add(path, device);
            next(device, MCTPDeviceState::Assigning);
            setupEndpoint(device);
            break;
        case MCTPDeviceState::Assigning:
        case MCTPDeviceState::Unassigned:
            break;
        case MCTPDeviceState::Assigned:
        {
            // EM may publish property changes without removal. Replace the
            // device so its state reflects EM's configuration.
            auto current = devices.deviceFor(path);
            if (!current)
            {
                warning(
                    "Invalid state: Failed to manage device for inventory at '{INVENTORY_PATH}', but the inventory item is unrecognised",
                    "INVENTORY_PATH", path);
                return;
            }

            // Unsynchronised termination so we can configure the new device.
            // Paired with presence test when handling MCTPDeviceState::Removing
            // in the subscribed endpoint removed handler
            terminate(current);
            current->remove();
            manageMCTPDevice(path, device);
            break;
        }
        case MCTPDeviceState::Quarantine:
            next(device, MCTPDeviceState::Assigning);
            break;
        case MCTPDeviceState::Lost:
        case MCTPDeviceState::Recovering:
            break;
        case MCTPDeviceState::Recovered:
            next(device, MCTPDeviceState::Assigned);
            break;
        case MCTPDeviceState::Removing:
            next(device, MCTPDeviceState::Pending);
            break;
        case MCTPDeviceState::Pending:
            break;
    }
}

void MCTPReactor::unmanageMCTPDevice(const sdbusplus::object_path& path)
{
    auto device = devices.deviceFor(path);
    if (!device)
    {
        debug("Unrecognised inventory item: {INVENTORY_PATH}", "INVENTORY_PATH",
              path);
        return;
    }

    debug("MCTP device inventory removed at '{INVENTORY_PATH}'",
          "INVENTORY_PATH", path);

    switch (states[device->id()])
    {
        case MCTPDeviceState::Unmanaged:
            break;
        case MCTPDeviceState::Assigning:
            next(device, MCTPDeviceState::Quarantine);
            break;
        case MCTPDeviceState::Unassigned:
            terminate(device);
            break;
        case MCTPDeviceState::Assigned:
            debug("Stopping management of MCTP device at [ {MCTP_DEVICE} ]",
                  "MCTP_DEVICE", device->describe());
            next(device, MCTPDeviceState::Removing);
            device->remove();
            break;
        case MCTPDeviceState::Quarantine:
            break;
        case MCTPDeviceState::Lost:
            terminate(device);
            break;
        case MCTPDeviceState::Recovering:
            next(device, MCTPDeviceState::Quarantine);
            break;
        case MCTPDeviceState::Recovered:
        case MCTPDeviceState::Removing:
            break;
        case MCTPDeviceState::Pending:
            next(device, MCTPDeviceState::Removing);
            break;
    }
}

void MCTPReactor::next(const std::shared_ptr<MCTPDevice>& dev,
                       const MCTPDeviceState next)
{
    debug(
        "Device {DEVICE_ID} ([ {DEVICE_DESCRIPTION} ]) transitioning from {CURRENT_STATE} to {NEXT_STATE}",
        "DEVICE_ID", lg2::hex, dev->id(), "DEVICE_DESCRIPTION", dev->describe(),
        "CURRENT_STATE", states[dev->id()], "NEXT_STATE", next);
    states[dev->id()] = next;
}

void MCTPReactor::terminate(const std::shared_ptr<MCTPDevice>& dev)
{
    debug(
        "Device {DEVICE_ID} ([ {DEVICE_DESCRIPTION} ]) terminated from {CURRENT_STATE}",
        "DEVICE_ID", lg2::hex, dev->id(), "DEVICE_DESCRIPTION", dev->describe(),
        "CURRENT_STATE", states[dev->id()]);
    devices.remove(dev);
    states.erase(dev->id());
}
