#include "boot_manager.hpp"

#include "utils.hpp"

#include <fmt/printf.h>

#include <string_view>
#include <vector>

namespace boot_time_monitor
{

namespace
{
constexpr uint32_t kMaxCheckpointCnt = 100;
constexpr uint32_t kMaxDurationCnt = 100;
} // namespace

/**
 * BootManager implementation class
 */
BootManager::BootManager(std::shared_ptr<UtilIface> util,
                         const std::shared_ptr<FileUtilIface>& cpCSV,
                         const std::shared_ptr<FileUtilIface>& durCSV) :
    util(std::move(util)),
    cpCSV(cpCSV), durCSV(durCSV)
{
    checkpoints = std::move(*cpCSV->loadCheckpoints(false));
    durations = std::move(*durCSV->loadDurations(false));
    preCheckpoints = std::move(*cpCSV->loadCheckpoints(true));
    preDurations = std::move(*durCSV->loadDurations(true));
}

void BootManager::setCheckpoint(std::string_view cpName,
                                int64_t externalWallTime, int64_t duration)
{
    auto wallTime = externalWallTime == 0 ? util->getWallTimeInMs()
                                          : externalWallTime;
    auto upTime = util->getUpTimeInMs();
    if (upTime == std::nullopt)
    {
        fmt::print("[{}] Can't get up time. Skip this checkpoint.\n",
                   __FUNCTION__);
        return;
    }
    if (!util->isValidName(cpName))
    {
        fmt::print(
            "[{}] Name is invalid. Only allows [0-9a-zA-Z_] but get: {}\n",
            __FUNCTION__, cpName);
        return;
    }

    if (checkpoints.size() >= kMaxCheckpointCnt)
    {
        fmt::print("[{}] Drop incoming checkpoint due to hit the limit. "
                   "name={}, externalWallTime={}, duration={}\n",
                   __FUNCTION__, cpName, externalWallTime, duration);
        return;
    }
    // `boot_manager` helps to calculate the transition time from one stage to
    // next stage if the user can provide a self measured duration for the
    // current stage.
    // For example, if the interval between checkpoint A and B is 10 seconds and
    // the user knows B stage only uses 8 seconds to boot up. Then that means 2
    // seconds transition time was cost from A stage to B stage.
    // `duration == 0` means "I don't have self measured duration, so no need to
    // calculate transition time for me".
    if (duration != 0)
    {
        checkpoints.emplace_back(
            std::string{kTransitionStagePrefix} + cpName.data(),
            wallTime - duration, upTime.value() - duration);
        cpCSV->addCheckpoint(checkpoints.back().name,
                             checkpoints.back().wallTime,
                             checkpoints.back().monoTime);

        if (checkpoints.size() >= kMaxCheckpointCnt)
        {
            fmt::print(
                "[{}] Incoming checkpoint has `duration` so `To_{}` has been "
                "created and added. Since the size is full so the incoming "
                "checkpoint has been dropped\n",
                __FUNCTION__, cpName);
            return;
        }
    }

    checkpoints.emplace_back(std::string{cpName}, wallTime, upTime.value());
    cpCSV->addCheckpoint(checkpoints.back().name, checkpoints.back().wallTime,
                         checkpoints.back().monoTime);
}

void BootManager::setDuration(std::string_view durName, int64_t duration)
{
    if (!util->isValidName(durName))
    {
        fmt::print(
            "[{}] Name is invalid. Only allows [0-9a-zA-Z_] but get: {}\n",
            __FUNCTION__, durName);
        return;
    }

    if (durations.size() >= kMaxDurationCnt)
    {
        fmt::print("[{}] Drop incoming duration due to hit the limit. "
                   "name={}, duration={}\n",
                   __FUNCTION__, durName, duration);
        return;
    }

    durations.emplace_back(std::string(durName), duration);
    durCSV->addDuration(durations.back().name, durations.back().duration);
}

void BootManager::notifyComplete()
{
    std::swap(preCheckpoints, checkpoints);
    checkpoints.clear();
    std::swap(preDurations, durations);
    durations.clear();

    cpCSV->completeCurrent();
    durCSV->completeCurrent();
}

bool BootManager::isRebooting()
{
    return !(cpCSV->isEmpty() && durCSV->isEmpty());
}

const std::vector<Checkpoint>& BootManager::getCheckpoints() const
{
    return checkpoints;
}

const std::vector<Duration>& BootManager::getDurations() const
{
    return durations;
}

const std::vector<Checkpoint>& BootManager::getPreCheckpoints() const
{
    return preCheckpoints;
}

const std::vector<Duration>& BootManager::getPreDurations() const
{
    return preDurations;
}

} // namespace boot_time_monitor
