#pragma once
#include <libnvme-mi.h>

#include <boost/algorithm/string/join.hpp>
#include <boost/asio.hpp>
#include <phosphor-logging/lg2.hpp>

#include <algorithm>
#include <chrono>
#include <cstdlib>
#include <filesystem>
#include <format>
#include <memory>
#include <mutex>
#include <optional>
#include <system_error>

namespace nvme
{
static constexpr const char* sensorType = "NVME1000";
} // namespace nvme

inline std::filesystem::path deriveRootBusPath(int busNumber)
{
    return "/sys/bus/i2c/devices/i2c-" + std::to_string(busNumber) +
           "/mux_device";
}

inline std::optional<int> deriveRootBus(std::optional<int> busNumber)
{
    if (!busNumber)
    {
        return std::nullopt;
    }

    std::filesystem::path muxPath = deriveRootBusPath(*busNumber);

    if (!std::filesystem::is_symlink(muxPath))
    {
        return *busNumber;
    }

    std::string rootName = std::filesystem::read_symlink(muxPath).filename();
    size_t dash = rootName.find('-');
    if (dash == std::string::npos)
    {
        lg2::error("Error finding root bus for {ROOT_NAME}", "ROOT_NAME",
                   rootName);
        return std::nullopt;
    }

    return std::stoi(rootName.substr(0, dash));
}

inline std::optional<std::string>
    extractOneFromTail(std::string::const_reverse_iterator& rbegin,
                       const std::string::const_reverse_iterator& rend)
{
    std::string name;
    auto curr = rbegin;
    // remove the ending '/'s
    while (rbegin != rend && *rbegin == '/')
    {
        rbegin++;
    }
    if (rbegin == rend)
    {
        return std::nullopt;
    }
    curr = rbegin++;

    // extract word
    while (rbegin != rend && *rbegin != '/')
    {
        rbegin++;
    }
    if (rbegin == rend)
    {
        return std::nullopt;
    }
    name.append(rbegin.base(), curr.base());
    return {name};
}

// a path of
// "/xyz/openbmc_project/inventory/system/board/{prod}/{nvme}/{substruct}..."
// will generates a sensor name {prod}_{nvme}_{substruct}...
inline std::optional<std::string>
    createSensorNameFromPath(const std::string& path)
{
    if (path.empty())
    {
        return std::nullopt;
    }
    auto rbegin = path.crbegin();
    std::vector<std::string> names;
    do
    {
        auto name = extractOneFromTail(rbegin, path.crend());
        if (!name)
        {
            return std::nullopt;
        }
        if (*name == "board")
        {
            break;
        }

        if (!names.empty() && names.back().starts_with(*name))
        {
            // Skip potential duplicate prefix
            continue;
        }
        names.push_back(*name);
    } while (rbegin != path.rend());

    std::reverse(names.begin(), names.end());
    auto sensorName = boost::algorithm::join(names, "_");
    return sensorName;
}

// Function to update NVMe temp sensor

// Function type for fetching ctemp which encaplucated in a structure of T.
// The fetcher function take a callback as input to process the result.
template <class T>
using ctemp_fetch_t =
    std::function<void(std::function<void(const std::error_code&, T)>&&)>;

// Function type for processing ctemp out the structure of type T.
// The process function will update the properties based on input data.
template <class T>
using ctemp_process_t =
    std::function<void(const std::error_code& error, T data)>;

template <class T>
void pollCtemp(
    const std::weak_ptr<boost::asio::steady_timer>& timer,
    std::chrono::duration<double, std::milli> delay,
    const std::function<void(std::function<void(const std::error_code&, T)>&&)>&
        dataFetcher,
    const std::function<void(const std::error_code& error, T data)>&
        dataProcessor);

namespace detail
{

template <class T>
void updateCtemp(std::weak_ptr<boost::asio::steady_timer> timer,
                 std::chrono::duration<double, std::milli> delay,
                 ctemp_process_t<T> dataProcessor, ctemp_fetch_t<T> dataFetcher,
                 const std::error_code& error, T data)
{
    if (timer.expired())
    {
        dataProcessor(std::make_error_code(std::errc::operation_canceled),
                      data);
        return;
    }

    dataProcessor(error, data);
    ::pollCtemp(std::move(timer), delay, dataFetcher, dataProcessor);
}

template <class T>
void pollCtemp(std::weak_ptr<boost::asio::steady_timer> timer,
               std::chrono::duration<double, std::milli> delay,
               ctemp_fetch_t<T> dataFetcher, ctemp_process_t<T> dataProcessor,
               const boost::system::error_code errorCode)
{
    if (errorCode == boost::asio::error::operation_aborted || timer.expired())
    {
        lg2::info("poll loop has been cancelled");
        return;
    }
    if (errorCode)
    {
        lg2::error("{ERROR}", "ERROR", errorCode.message());
        ::pollCtemp(std::move(timer), delay, dataFetcher, dataProcessor);
        return;
    }

    dataFetcher(std::bind_front(detail::updateCtemp<T>, std::move(timer), delay,
                                dataProcessor, dataFetcher));
}

} // namespace detail

template <class T>
void pollCtemp(
    const std::weak_ptr<boost::asio::steady_timer>& weakTimer,
    std::chrono::duration<double, std::milli> delay,
    const std::function<void(std::function<void(const std::error_code&, T)>&&)>&
        dataFetcher,
    const std::function<void(const std::error_code& error, T data)>&
        dataProcessor)
{
    auto timer = weakTimer.lock();
    if (!timer)
    {
        return;
    }
    timer->expires_after(
        std::chrono::duration_cast<std::chrono::milliseconds>(delay));
    timer->async_wait(std::bind_front(detail::pollCtemp<T>, timer, delay,
                                      dataFetcher, dataProcessor));
}

// Strips space padding from a NVMe string, replaces invalid characters with
// spaces.
static inline std::string nvmeString(const char* data, size_t size)
{
    std::string s(data, size);

    size_t n = s.find_last_not_of(' ');
    if (n == std::string::npos)
    {
        s.clear();
    }
    else
    {
        s.resize(n + 1);
    }

    for (auto& c : s)
    {
        if (c < 0x20 || c > 0x7e)
        {
            c = ' ';
        }
    }
    return s;
}

static inline uint64_t char128ToUint64(const unsigned char* data)
{
    int i = 0;
    uint64_t result = 0;

    for (i = 0; i < 16; i++)
    {
        result *= 256;
        result += data[15 - i];
    }
    return result;
}

// Helper functions to extract endpoint / controller descriptor from
// nvme_mi_ctrl_t.
// TODO: Replace with upstream API nvme_mi_controller_desc(nvme_mi_ctrl_t ctrl)
// once available in libnvme.
inline uint16_t getCtrlId(nvme_mi_ctrl_t ctrl)
{
    // NOLINTBEGIN(cppcoreguidelines-pro-type-reinterpret-cast)
    return *reinterpret_cast<const uint16_t*>(
        reinterpret_cast<const uint8_t*>(ctrl) +
        std::max(sizeof(uint16_t), sizeof(void*)));
    // NOLINTEND(cppcoreguidelines-pro-type-reinterpret-cast)
}

inline std::string describeCtrl(nvme_mi_ctrl_t ctrl)
{
    if (ctrl == nullptr)
    {
        return "null";
    }
    /*
     * Internal layout from libnvme private.h:
     * struct nvme_mi_ctrl {
     *     struct nvme_mi_ep *ep;
     *     __u16 id;
     *     struct list_node ep_entry;
     * };
     */
    // NOLINTBEGIN(cppcoreguidelines-pro-type-reinterpret-cast)
    auto* ep = *reinterpret_cast<nvme_mi_ep_t*>(ctrl);
    // NOLINTEND(cppcoreguidelines-pro-type-reinterpret-cast)
    uint16_t id = getCtrlId(ctrl);

    if (ep != nullptr)
    {
        std::unique_ptr<char, decltype(&std::free)> epDesc(
            nvme_mi_endpoint_desc(ep), &std::free);
        if (epDesc != nullptr)
        {
            return std::format("{}:ctrl-{}", epDesc.get(), id);
        }
    }
    return std::format("ctrl-{}", id);
}
