#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(
            cpName.data() + std::string{kBeginStageSuffix},
            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
