#include "NVMeDevice.hpp"

#include <boost/system/detail/error_code.hpp>

#include <cassert>

void NVMeDevice::start()
{
    subsys->start();

    if (intf.getProtocol() == NVMeIntf::Protocol::NVMeMI)
    {
        setup();
    }
}

void NVMeDevice::setup()
{
    dev->setup(
        [weak{weak_from_this()}](const std::error_code& ec,
                                 const std::shared_ptr<MctpEndpoint>& ep) {
        if (auto self = weak.lock())
        {
            self->finalize(ec, ep);
        }
    });
}

void NVMeDevice::stop()
{
    subsys->stop();
}

void NVMeDevice::finalize(const std::error_code& ec,
                          const std::shared_ptr<MctpEndpoint>& ep)
{
    assert(intf.getProtocol() == NVMeIntf::Protocol::NVMeMI);

    if (ec)
    {
        restart();
        return;
    }

    ep->subscribe(
        [weak{weak_from_this()}](const std::shared_ptr<MctpEndpoint>& ep) {
        if (auto self = weak.lock())
        {
            self->degraded(ep);
        }
    },
        [weak{weak_from_this()}](const std::shared_ptr<MctpEndpoint>& ep) {
        if (auto self = weak.lock())
        {
            self->available(ep);
        }
    },
        // Removed
        [weak{weak_from_this()}](const std::shared_ptr<MctpEndpoint>& ep) {
        if (auto self = weak.lock())
        {
            self->removed(ep);
        }
    });
}

void NVMeDevice::restart()
{
    assert(intf.getProtocol() == NVMeIntf::Protocol::NVMeMI);
    assert(timer);
    assert(gracePeriod);
    // Setup failed, wait a bit and try again
    timer->expires_after(*gracePeriod);
    timer->async_wait(
        [weak{weak_from_this()}](const boost::system::error_code& ec) {
        if (ec)
        {
            return;
        }

        if (auto self = weak.lock())
        {
            self->setup();
        }
    });
}

void NVMeDevice::degraded(const std::shared_ptr<MctpEndpoint>& ep)
{
    assert(intf.getProtocol() == NVMeIntf::Protocol::NVMeMI);
    std::cout << "[" << ep->describe() << "]: Degraded\n";
    recovering = true;
    timer->cancel();
    std::get<std::shared_ptr<NVMeMiIntf>>(intf.getInferface())->stop();
}

void NVMeDevice::available(const std::shared_ptr<MctpEndpoint>& ep)
{
    assert(intf.getProtocol() == NVMeIntf::Protocol::NVMeMI);
    assert(timer);
    assert(gracePeriod);
    std::cout << subsys->getName() << " [" << ep->describe()
              << "]: Available\n";

    // The behaviour of MctpEndpoint::subscribe() is to register the provided
    // callbacks, and then fetch the current state of the endpoint. As a
    // consequence of fetching the state, the appropriate callback is be
    // invoked.
    //
    // Unless circumstances are particularly rough, the endpoint will be in the
    // 'Available' state when it is first exposed on DBus.
    //
    // Beyond the start-up entry to the 'Available' state, we will only see an
    // 'Available' event if something has triggered endpoint recovery (putting
    // the endpoint into 'Degraded'), followed by the recovery succeeding.
    //
    // However, it's possible that recovery is triggered by the NVMe MI layer
    // being broken, while the MCTP endpoint continues to respond without error.
    // This can lead to a "tight" event cycle of entering 'Degraded',
    // immediately followed by entering 'Available', where NVMeMi::start() kicks
    // off the endpoint recovery again as the MI layer continues to fail.
    //
    // The impact of this event cycle is exacerbated by `nvme_mi_open_mctp()`
    // performing IO to the device for the purpose of quirk detection. Currently
    // `nvme_mi_open_mctp()` is issued on the main thread, and if the MI
    // layer is dead enough, the device fails to respond to the Admin Identify
    // command. The failure to respond blocks the main thread for the default
    // libnvme-mi command timeout (which, upstream, is 5000ms). This can lead
    // to misbehaviour of applications interacting with the DBus objects exposed
    // by nvmesensor.
    //
    // Mitigate the hazard of this event cycle by enforcing a grace-period after
    // MCTP endpoint recovery succeeds. This can provide some time for other
    // jobs on the main thread to be processed.
    //
    // We track whether the grace period is required via the `recovering`
    // boolean. If we've passed through the 'Degraded' state then we know we're
    // at risk of the tight event cycle, therefore we enforce the grace-period.
    // If we've not passed through 'Degraded' but we have an 'Available' event
    // we know we're in the start-up path, which we don't want to delay.
    if (recovering)
    {
        recovering = false;
        timer->expires_after(*gracePeriod);
        timer->async_wait(
            [weak{weak_from_this()}, ep](const boost::system::error_code& ec) {
            if (ec)
            {
                return;
            }
            if (auto self = weak.lock())
            {
                std::get<std::shared_ptr<NVMeMiIntf>>(self->intf.getInferface())
                    ->start(ep);
            }
        });
    }
    else
    {
        // If we're not recovering we should only see an 'Available' event
        // when we're first initialising the device. There should be no timers
        // to cancel.
        std::size_t cancelled = timer->cancel();
        if (cancelled != 0)
        {
            std::cerr << "[ " << ep->describe()
                      << "]: Unexpected timer cancellation (" << cancelled
                      << ") in non-recovery path!\n";
        }
        std::get<std::shared_ptr<NVMeMiIntf>>(intf.getInferface())->start(ep);
    }
}

void NVMeDevice::removed(const std::shared_ptr<MctpEndpoint>& ep)
{
    assert(intf.getProtocol() == NVMeIntf::Protocol::NVMeMI);
    std::cout << "[" << ep->describe() << "]: Removed\n";
    recovering = false;
    std::get<std::shared_ptr<NVMeMiIntf>>(intf.getInferface())->stop();
    restart();
}
