#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
