#include "utils.hpp"

#include <fmt/printf.h>

#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/mapped_region.hpp>

#include <array>
#include <chrono>
#include <filesystem>
#include <fstream>
#include <memory>
#include <optional>
#include <regex>
#include <string>
#include <string_view>
#include <vector>

namespace boot_time_monitor
{

namespace fs = std::filesystem;

std::optional<int64_t> Util::getUpTimeInMs()
{
    constexpr int32_t kMillisecondPerSecond = 1000;
    std::ifstream fin("/proc/uptime");
    if (!fin.is_open())
    {
        fmt::print(stderr, "[{}]: Can not read \"/proc/uptime\"\n",
                   __FUNCTION__);
        return std::nullopt;
    }
    double uptimeSec;
    fin >> uptimeSec;
    fin.close();

    return static_cast<int64_t>(uptimeSec * kMillisecondPerSecond);
}

inline int64_t Util::getWallTimeInMs()
{
    return std::chrono::system_clock::now().time_since_epoch() /
           std::chrono::milliseconds(1);
}

inline bool Util::isValidName(std::string_view name)
{
    return !std::regex_search(name.data(), std::regex("[^0-9a-zA-Z_:]"));
}

inline std::string Util::getCPPath(std::string_view nodeName,
                                   bool wantCompleted)
{
    return kBTMonitorDir + nodeName.data() + "_" + kCheckpointFile +
           (wantCompleted ? kCompletedSuffix : "");
}

inline std::string Util::getDurPath(std::string_view nodeName,
                                    bool wantCompleted)
{
    return kBTMonitorDir + nodeName.data() + "_" + kDurationFile +
           (wantCompleted ? kCompletedSuffix : "");
}

std::optional<uint32_t> Util::readMem4Bytes(uint32_t target)
{
    // Typically the pageSize will be 4K/8K for 32 bit operating systems
    uint32_t pageSize = boost::interprocess::mapped_region::get_page_size();
    const uint32_t kPageMask = pageSize - 1;

    uint32_t pageOffset = target & (~kPageMask);
    uint32_t offsetInPage = target & kPageMask;

    // Map `/dev/mem` to a region.
    std::unique_ptr<boost::interprocess::file_mapping> fileMapping;
    std::unique_ptr<boost::interprocess::mapped_region> MappedRegion;
    try
    {
        fileMapping = std::make_unique<boost::interprocess::file_mapping>(
            "/dev/mem", boost::interprocess::read_only);
        // No need to unmap in the end.
        MappedRegion = std::make_unique<boost::interprocess::mapped_region>(
            *fileMapping, boost::interprocess::read_only, pageOffset,
            pageSize * 2);

        // MappedRegion->get_address() returns (void*) which needs to covert
        // into (char*) to make `+ offsetInPage` work.
        // Then converts it again into (uint32_t*) since we read 4 bytes.
        return *(reinterpret_cast<uint32_t*>(
            static_cast<char*>(MappedRegion->get_address()) + offsetInPage));
    }
    catch (const std::exception& e)
    {
        fmt::print(stderr, "[{}]: Throw exception: %s\n", __FUNCTION__,
                   e.what());
        return std::nullopt;
    }

    fmt::print(stderr, "[{}]: Shouldn't go to this line.\n", __FUNCTION__);
    return std::nullopt;
}

FileUtil::FileUtil(std::string_view filename) : filename(filename)
{
    fs::path dir = fs::path(filename).remove_filename();
    if (!dir.empty() && !fs::exists(dir))
    {
        fs::create_directories(dir);
    }
    ofs = std::make_unique<std::ofstream>(
        filename.data(), std::fstream::out | std::fstream::app);
    if (!ofs->good())
    {
        throw std::invalid_argument("ofstream is not available.");
    }
}

void FileUtil::addCheckpoint(std::string_view name, int64_t wallTimeInMs,
                             int64_t monoTimeInMs)
{
    (*ofs) << name << "," << wallTimeInMs << "," << monoTimeInMs << '\n';
    ofs->flush();
}

void FileUtil::addDuration(std::string_view name, int64_t durationInMs)
{
    (*ofs) << name << "," << durationInMs << '\n';
    ofs->flush();
}

void FileUtil::completeCurrent()
{
    ofs->close();
    fs::rename(filename, filename + kCompletedSuffix);

    // Reopen for next reboot
    ofs->open(filename.c_str(), std::fstream::out | std::fstream::app);
    if (!ofs->good())
    {
        throw std::invalid_argument("ofstream is not available.");
    }
}

std::unique_ptr<std::vector<Checkpoint>>
    FileUtil::loadCheckpoints(bool loadCompleted)
{
    std::unique_ptr<std::vector<Checkpoint>> result =
        std::make_unique<std::vector<Checkpoint>>();
    std::string cpFilename = filename + (loadCompleted ? kCompletedSuffix : "");
    std::ifstream ifs(cpFilename);
    if (!ifs.good())
    {
        fmt::print("[{}] Failed to load `{}`. Skip it.\n", __FUNCTION__,
                   cpFilename);
        return result;
    }

    constexpr uint32_t kBufSize = 1024;
    constexpr uint32_t kMatchCount = 4;

    std::array<char, kBufSize> buf;
    std::cmatch match;
    const std::regex reg("^([0-9a-zA-Z_:]*),([0-9]+),([0-9]+)$");
    while (ifs.getline(buf.data(), kBufSize))
    {
        if (regex_match(buf.data(), match, reg))
        {
            if (match.size() != kMatchCount)
            {
                // This line is problematic. Skip it.
                continue;
            }

            result->emplace_back(match[1].str(), std::stoll(match[2].str()),
                                 std::stoll(match[3].str()));
        }
    }
    return result;
}

std::unique_ptr<std::vector<Duration>>
    FileUtil::loadDurations(bool loadCompleted)
{
    std::unique_ptr<std::vector<Duration>> result =
        std::make_unique<std::vector<Duration>>();
    std::string durFilename = filename +
                              (loadCompleted ? kCompletedSuffix : "");
    std::ifstream ifs(durFilename);
    if (!ifs.good())
    {
        fmt::print("[{}] Failed to load `{}`. Skip it.\n", __FUNCTION__,
                   durFilename);
        return result;
    }

    constexpr uint32_t kBufSize = 1024;
    constexpr uint32_t kMatchCount = 3;

    std::array<char, kBufSize> buf;
    std::cmatch match;
    const std::regex reg("^([0-9a-zA-Z_:]*),([0-9]+)$");
    while (ifs.getline(buf.data(), kBufSize))
    {
        if (regex_match(buf.data(), match, reg))
        {
            if (match.size() != kMatchCount)
            {
                // This line is problematic. Skip it.
                continue;
            }

            result->emplace_back(match[1].str(), std::stoll(match[2].str()));
        }
    }
    return result;
}

bool FileUtil::isEmpty()
{
    const auto result = ofs->tellp();
    if (result < 0)
    {
        throw std::runtime_error("File can't be `tellp`");
    }

    return result == 0;
}

} // namespace boot_time_monitor
