#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 << std::endl;
    ofs->flush();
}

void FileUtil::addDuration(std::string_view name, int64_t durationInMs)
{
    (*ofs) << name << "," << durationInMs << std::endl;
    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
