#include "NVMeVolume.hpp"

#include "NVMeCacheImpl.hpp"

using SchedulerClockType = std::chrono::steady_clock;

NVMeVolume::NVMeVolume(sdbusplus::asio::object_server& objServer,
                       const std::shared_ptr<sdbusplus::asio::connection>& conn,
                       const std::shared_ptr<NVMeSubsystem>& subsys,
                       const NVMeNSIdentify& ns) :
    VolumeBase(dynamic_cast<sdbusplus::bus_t&>(*conn),
               subsys->volumePath(ns.namespaceId).c_str()),
    NvmeVolumeBase(dynamic_cast<sdbusplus::bus_t&>(*conn),
                   subsys->volumePath(ns.namespaceId).c_str()),
    path(subsys->volumePath(ns.namespaceId)), objServer(objServer), conn(conn),
    subsys(subsys)
{
    namespaceId(ns.namespaceId, false);
    size(ns.size, false);
    blockSize(ns.blockSize, false);
    lbaFormat(ns.lbaFormat, false);
    metadataAtEnd(ns.metadataAtEnd, false);

    // see init() for other initialisation
}

void NVMeVolume::init()
{
    deleteInterface =
        objServer.add_interface(path, "xyz.openbmc_project.Object.Delete");
    deleteInterface->register_method(
        "Delete", [weak{weak_from_this()}](boost::asio::yield_context yield) {
        auto self = weak.lock();
        if (!self)
        {
            throw std::runtime_error("volume delete called twice?");
        }
        auto subsys = self->subsys.lock();
        if (!subsys)
        {
            throw std::runtime_error("nvmesensor is shutting down");
        }
        subsys->deleteVolume(std::move(yield), self);
    });
    deleteInterface->initialize();

    VolumeBase::emit_added();
    NvmeVolumeBase::emit_added();

    /* create the MetricStore interface */
    auto scheduler = Scheduler<SchedulerClockType>::getScheduler(path);

    using IdentifyMetric =
        IdentifyMetric<NVME_IDENTIFY_CNS_NS, SchedulerClockType>;

    // NOLINTBEGIN(modernize-make-shared)
    auto identify = std::shared_ptr<IdentifyMetric>(
        new IdentifyMetric(this->shared_from_this(), scheduler,
                           // Identify info is persist throughout the namespace
                           // lifecycle i.e. from start() to stop()
                           IdentifyMetric::ClockType::duration::max()));
    // NOLINTEND(modernize-make-shared)

    metricStore.emplace(conn->get_io_context(), conn, path,
                        std::move(identify));
}

std::shared_ptr<NVMeVolume>
    NVMeVolume::create(sdbusplus::asio::object_server& objServer,
                       const std::shared_ptr<sdbusplus::asio::connection>& conn,
                       const std::shared_ptr<NVMeSubsystem>& subsys,
                       const NVMeNSIdentify& ns)
{
    auto self = std::shared_ptr<NVMeVolume>(
        new NVMeVolume(objServer, conn, subsys, ns));
    self->init();
    return self;
}

NVMeVolume::~NVMeVolume()
{
    metricStore.reset();
    NvmeVolumeBase::emit_removed();
    VolumeBase::emit_removed();
    objServer.remove_interface(deleteInterface);
}

void NVMeVolume::erase(VolumeBase::EraseMethod eraseType)
{
    (void)eraseType;
    // TODO: will need dbus async method handling.
    throw std::runtime_error("volume erase not yet implemented");
}

// Additional methods on Volume that are not relevant.

void NVMeVolume::formatLuks([[maybe_unused]] std::vector<uint8_t> password,
                            [[maybe_unused]] VolumeBase::FilesystemType type)
{
    throw std::runtime_error("Method Not Supported");
}

void NVMeVolume::lock()
{
    throw std::runtime_error("Method Not Supported");
}

void NVMeVolume::unlock([[maybe_unused]] std::vector<uint8_t> password)
{
    throw std::runtime_error("Method Not Supported");
}

void NVMeVolume::changePassword(
    [[maybe_unused]] std::vector<uint8_t> oldPassword,
    [[maybe_unused]] std::vector<uint8_t> newPassword)
{
    throw std::runtime_error("Method Not Supported");
}
