// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "metric.hpp"

#include "metricblob.pb.h"

#include "util.hpp"

#include <sys/statvfs.h>

#include <phosphor-logging/log.hpp>

#include <cstdint>
#include <filesystem>
#include <sstream>
#include <string>
#include <string_view>

namespace metric_blob
{

using phosphor::logging::entry;
using phosphor::logging::log;
using level = phosphor::logging::level;

BmcHealthSnapshot::BmcHealthSnapshot() :
    done(false), stringId(0), ticksPerSec(0)
{}

struct ProcStatEntry
{
    std::string cmdline;
    std::string tcomm;
    float utime;
    float stime;

    // Processes with the longest utime + stime are ranked first.
    // Tie breaking is done with cmdline then tcomm.
    bool operator<(const ProcStatEntry& other) const
    {
        const float negTime = -(utime + stime);
        const float negOtherTime = -(other.utime + other.stime);
        return std::tie(negTime, cmdline, tcomm) <
               std::tie(negOtherTime, other.cmdline, other.tcomm);
    }
};

bmcmetrics::metricproto::BmcProcStatMetric BmcHealthSnapshot::getProcStatList()
{
    constexpr std::string_view procPath = "/proc/";

    bmcmetrics::metricproto::BmcProcStatMetric ret;
    std::vector<ProcStatEntry> entries;

    for (const auto& procEntry : std::filesystem::directory_iterator(procPath))
    {
        const std::string& path = procEntry.path();
        int pid = -1;
        if (isNumericPath(path, pid))
        {
            ProcStatEntry entry;

            try
            {
                entry.cmdline = getCmdLine(pid);
                TcommUtimeStime t = getTcommUtimeStime(pid, ticksPerSec);
                entry.tcomm = t.tcomm;
                entry.utime = t.utime;
                entry.stime = t.stime;

                entries.push_back(entry);
            }
            catch (const std::exception& e)
            {
                log<level::ERR>("Could not obtain process stats");
            }
        }
    }

    std::sort(entries.begin(), entries.end());

    bool isOthers = false;
    ProcStatEntry others;
    others.cmdline = "(Others)";
    others.utime = others.stime = 0;

    // Only show this many processes and aggregate all remaining ones into
    // "others" in order to keep the size of the snapshot reasonably small.
    // With 10 process stat entries and 10 FD count entries, the size of the
    // snapshot reaches around 1.5KiB. This is non-trivial, and we have to set
    // the collection interval long enough so as not to over-stress the IPMI
    // interface and the data collection service. The value of 10 is chosen
    // empirically, it might be subject to adjustments when the system is
    // launched later.
    constexpr int topN = 10;

    for (size_t i = 0; i < entries.size(); ++i)
    {
        if (i >= topN)
        {
            isOthers = true;
        }

        ProcStatEntry& entry = entries[i];

        if (isOthers)
        {
            others.utime += entry.utime;
            others.stime += entry.stime;
        }
        else
        {
            bmcmetrics::metricproto::BmcProcStatMetric::BmcProcStat s;
            std::string fullCmdline = entry.cmdline;
            if (entry.tcomm.size() > 0)
            {
                fullCmdline += " " + entry.tcomm;
            }
            s.set_sidx_cmdline(getStringID(fullCmdline));
            s.set_utime(entry.utime);
            s.set_stime(entry.stime);
            *(ret.add_stats()) = s;
        }
    }

    if (isOthers)
    {
        bmcmetrics::metricproto::BmcProcStatMetric::BmcProcStat s;
        s.set_sidx_cmdline(getStringID(others.cmdline));
        s.set_utime(others.utime);
        s.set_stime(others.stime);
        *(ret.add_stats()) = s;
    }

    return ret;
}

int getFdCount(int pid)
{
    const std::string& fdPath = "/proc/" + std::to_string(pid) + "/fd";
    return std::distance(std::filesystem::directory_iterator(fdPath),
                         std::filesystem::directory_iterator{});
}

struct FdStatEntry
{
    int fdCount;
    std::string cmdline;
    std::string tcomm;

    // Processes with the largest fdCount goes first.
    // Tie-breaking using cmdline then tcomm.
    bool operator<(const FdStatEntry& other) const
    {
        const int negFdCount = -fdCount;
        const int negOtherFdCount = -other.fdCount;
        return std::tie(negFdCount, cmdline, tcomm) <
               std::tie(negOtherFdCount, other.cmdline, other.tcomm);
    }
};

bmcmetrics::metricproto::BmcFdStatMetric BmcHealthSnapshot::getFdStatList()
{
    bmcmetrics::metricproto::BmcFdStatMetric ret;

    // Sort by fd count, no tie-breaking
    std::vector<FdStatEntry> entries;

    const std::string_view procPath = "/proc/";
    for (const auto& procEntry : std::filesystem::directory_iterator(procPath))
    {
        const std::string& path = procEntry.path();
        int pid = 0;
        FdStatEntry entry;
        if (isNumericPath(path, pid))
        {
            try
            {
                entry.fdCount = getFdCount(pid);
                TcommUtimeStime t = getTcommUtimeStime(pid, ticksPerSec);
                entry.cmdline = getCmdLine(pid);
                entry.tcomm = t.tcomm;
                entries.push_back(entry);
            }
            catch (const std::exception& e)
            {
                log<level::ERR>("Could not get file descriptor stats");
            }
        }
    }

    std::sort(entries.begin(), entries.end());

    bool isOthers = false;

    // Only report the detailed fd count and cmdline for the top 10 entries,
    // and collapse all others into "others".
    constexpr int topN = 10;

    FdStatEntry others;
    others.cmdline = "(Others)";
    others.fdCount = 0;

    for (size_t i = 0; i < entries.size(); ++i)
    {
        if (i >= topN)
        {
            isOthers = true;
        }

        const FdStatEntry& entry = entries[i];
        if (isOthers)
        {
            others.fdCount += entry.fdCount;
        }
        else
        {
            bmcmetrics::metricproto::BmcFdStatMetric::BmcFdStat s;
            std::string fullCmdline = entry.cmdline;
            if (entry.tcomm.size() > 0)
            {
                fullCmdline += " " + entry.tcomm;
            }
            s.set_sidx_cmdline(getStringID(fullCmdline));
            s.set_fd_count(entry.fdCount);
            *(ret.add_stats()) = s;
        }
    }

    if (isOthers)
    {
        bmcmetrics::metricproto::BmcFdStatMetric::BmcFdStat s;
        s.set_sidx_cmdline(getStringID(others.cmdline));
        s.set_fd_count(others.fdCount);
        *(ret.add_stats()) = s;
    }

    return ret;
}

void BmcHealthSnapshot::serializeSnapshotToArray(
    const bmcmetrics::metricproto::BmcMetricSnapshot& snapshot)
{
    size_t size = snapshot.ByteSizeLong();
    if (size > 0)
    {
        pbDump.resize(size);
        if (!snapshot.SerializeToArray(pbDump.data(), size))
        {
            log<level::ERR>("Could not serialize protobuf to array");
        }
    }
}

void BmcHealthSnapshot::doWork()
{
    bmcmetrics::metricproto::BmcMetricSnapshot snapshot;

    // Memory info
    std::string meminfoBuffer = readFileThenGrepIntoString("/proc/meminfo");

    {
        bmcmetrics::metricproto::BmcMemoryMetric m;

        std::string_view sv(meminfoBuffer.data());
        // MemAvailable
        int value;
        bool ok = parseMeminfoValue(sv, "MemAvailable:", value);
        if (ok)
        {
            m.set_mem_available(value);
        }

        ok = parseMeminfoValue(sv, "Slab:", value);
        if (ok)
        {
            m.set_slab(value);
        }

        ok = parseMeminfoValue(sv, "KernelStack:", value);
        if (ok)
        {
            m.set_kernel_stack(value);
        }

        *(snapshot.mutable_memory_metric()) = m;
    }

    // Uptime
    std::string uptimeBuffer = readFileThenGrepIntoString("/proc/uptime");
    double uptime = 0;
    double idleProcessTime = 0;
    BootTimesMonotonic btm;
    if (!parseProcUptime(uptimeBuffer, uptime, idleProcessTime))
    {
        log<level::ERR>("Error parsing /proc/uptime");
    }
    else if (!getBootTimesMonotonic(btm))
    {
        log<level::ERR>("Could not get boot time");
    }
    else
    {
        bmcmetrics::metricproto::BmcUptimeMetric m1;
        m1.set_uptime(uptime);
        m1.set_idle_process_time(idleProcessTime);
        if (btm.firmwareTime == 0 && btm.powerOnSecCounterTime != 0)
        {
            m1.set_firmware_boot_time_sec(
                static_cast<double>(btm.powerOnSecCounterTime) - uptime);
        }
        else
        {
            m1.set_firmware_boot_time_sec(
                static_cast<double>(btm.firmwareTime - btm.loaderTime) / 1e6);
        }
        m1.set_loader_boot_time_sec(static_cast<double>(btm.loaderTime) / 1e6);
        // initrf presents
        if (btm.initrdTime != 0)
        {
            m1.set_kernel_boot_time_sec(static_cast<double>(btm.initrdTime) /
                                        1e6);
            m1.set_initrd_boot_time_sec(
                static_cast<double>(btm.userspaceTime - btm.initrdTime) / 1e6);
            m1.set_userspace_boot_time_sec(
                static_cast<double>(btm.finishTime - btm.userspaceTime) / 1e6);
        }
        else
        {
            m1.set_kernel_boot_time_sec(static_cast<double>(btm.userspaceTime) /
                                        1e6);
            m1.set_initrd_boot_time_sec(0);
            m1.set_userspace_boot_time_sec(
                static_cast<double>(btm.finishTime - btm.userspaceTime) / 1e6);
        }
        *(snapshot.mutable_uptime_metric()) = m1;
    }

    // Storage space
    struct statvfs fiData;
    if ((statvfs("/", &fiData)) < 0)
    {
        log<level::ERR>("Could not call statvfs");
    }
    else
    {
        uint64_t kib = (fiData.f_bsize * fiData.f_bfree) / 1024;
        bmcmetrics::metricproto::BmcDiskSpaceMetric m2;
        m2.set_rwfs_kib_available(static_cast<int>(kib));
        *(snapshot.mutable_storage_space_metric()) = m2;
    }

    // The next metrics require a sane ticks_per_sec value, typically 100 on
    // the BMC. In the very rare circumstance when it's 0, exit early and return
    // a partially complete snapshot (no process).
    ticksPerSec = getTicksPerSec();

    // FD stat
    *(snapshot.mutable_fdstat_metric()) = getFdStatList();

    if (ticksPerSec == 0)
    {
        log<level::ERR>("ticksPerSec is 0, skipping the process list metric");
        serializeSnapshotToArray(snapshot);
        done = true;
        return;
    }

    // Proc stat
    *(snapshot.mutable_procstat_metric()) = getProcStatList();

    // String table
    std::vector<std::string_view> strings(stringTable.size());
    for (const auto& [s, i] : stringTable)
    {
        strings[i] = s;
    }

    bmcmetrics::metricproto::BmcStringTable st;
    for (size_t i = 0; i < strings.size(); ++i)
    {
        bmcmetrics::metricproto::BmcStringTable::StringEntry entry;
        entry.set_value(strings[i].data());
        *(st.add_entries()) = entry;
    }
    *(snapshot.mutable_string_table()) = st;

    // Save to buffer
    serializeSnapshotToArray(snapshot);
    done = true;
}

// BmcBlobSessionStat (9) but passing meta as reference instead of pointer,
// since the metadata must not be null at this point.
bool BmcHealthSnapshot::stat(blobs::BlobMeta& meta)
{
    if (!done)
    {
        // Bits 8~15 are blob-specific state flags.
        // For this blob, bit 8 is set when metric collection is still in
        // progress.
        meta.blobState |= (1 << 8);
    }
    else
    {
        meta.blobState = 0;
        meta.blobState = blobs::StateFlags::open_read;
        meta.size = pbDump.size();
    }
    return true;
}

std::string_view BmcHealthSnapshot::read(uint32_t offset,
                                         uint32_t requestedSize)
{
    uint32_t size = static_cast<uint32_t>(pbDump.size());
    if (offset >= size)
    {
        return {};
    }
    return std::string_view(pbDump.data() + offset,
                            std::min(requestedSize, size - offset));
}

int BmcHealthSnapshot::getStringID(const std::string_view s)
{
    int ret = 0;
    auto itr = stringTable.find(s.data());
    if (itr == stringTable.end())
    {
        stringTable[s.data()] = stringId;
        ret = stringId;
        ++stringId;
    }
    else
    {
        ret = itr->second;
    }
    return ret;
}

} // namespace metric_blob