/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * 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.
 */

#define LOG_TAG "perfstatsd_cpu"

#include "cpu_usage.h"
#include <android-base/stringprintf.h>
#include <android-base/strings.h>

using namespace android::pixel::perfstatsd;

static bool cDebug = false;
static constexpr char FMT_CPU_TOTAL[] =
    "[CPU: %lld.%03llds][T:%.2f%%,U:%.2f%%,S:%.2f%%,IO:%.2f%%]";
static constexpr char TOP_HEADER[] = "[CPU_TOP]  PID, PROCESS_NAME, USR_TIME, SYS_TIME\n";
static constexpr char FMT_TOP_PROFILE[] = "%6.2f%%   %5d %s %" PRIu64 " %" PRIu64 "\n";

CpuUsage::CpuUsage(void) {
    std::string procstat;
    if (android::base::ReadFileToString("/proc/stat", &procstat)) {
        std::istringstream stream(procstat);
        std::string line;
        while (getline(stream, line)) {
            std::vector<std::string> fields = android::base::Split(line, " ");
            if (fields[0].find("cpu") != std::string::npos && fields[0] != "cpu") {
                CpuData data;
                mPrevCoresUsage.push_back(data);
            }
        }
    }
    mCores = mPrevCoresUsage.size();
    mProfileThreshold = CPU_USAGE_PROFILE_THRESHOLD;
    mTopcount = TOP_PROCESS_COUNT;
}

void CpuUsage::setOptions(const std::string &key, const std::string &value) {
    if (key == PROCPROF_THRESHOLD || key == CPU_DISABLED || key == CPU_DEBUG ||
        key == CPU_TOPCOUNT) {
        uint32_t val = 0;
        if (!base::ParseUint(value, &val)) {
            LOG_TO(SYSTEM, ERROR) << "Invalid value: " << value;
            return;
        }

        if (key == PROCPROF_THRESHOLD) {
            mProfileThreshold = val;
            LOG_TO(SYSTEM, INFO) << "set profile threshold " << mProfileThreshold;
        } else if (key == CPU_DISABLED) {
            mDisabled = (val != 0);
            LOG_TO(SYSTEM, INFO) << "set disabled " << mDisabled;
        } else if (key == CPU_DEBUG) {
            cDebug = (val != 0);
            LOG_TO(SYSTEM, INFO) << "set debug " << cDebug;
        } else if (key == CPU_TOPCOUNT) {
            mTopcount = val;
            LOG_TO(SYSTEM, INFO) << "set top count " << mTopcount;
        }
    }
}

void CpuUsage::profileProcess(std::string *out) {
    // Read cpu usage per process and find the top ones
    DIR *dir;
    struct dirent *ent;
    std::unordered_map<uint32_t, ProcData> procUsage;
    std::priority_queue<ProcData, std::vector<ProcData>, ProcdataCompare> procList;
    if ((dir = opendir("/proc/")) != NULL) {
        while ((ent = readdir(dir)) != NULL) {
            if (ent->d_type == DT_DIR) {
                std::string pidStr = ent->d_name;
                std::string::const_iterator it = pidStr.begin();
                while (it != pidStr.end() && isdigit(*it)) ++it;
                if (!pidStr.empty() && it == pidStr.end()) {
                    std::string pidStat;
                    if (android::base::ReadFileToString("/proc/" + pidStr + "/stat", &pidStat)) {
                        std::vector<std::string> fields = android::base::Split(pidStat, " ");
                        uint32_t pid = 0;
                        uint64_t utime = 0;
                        uint64_t stime = 0;
                        uint64_t cutime = 0;
                        uint64_t cstime = 0;

                        if (!base::ParseUint(fields[0], &pid) ||
                            !base::ParseUint(fields[13], &utime) ||
                            !base::ParseUint(fields[14], &stime) ||
                            !base::ParseUint(fields[15], &cutime) ||
                            !base::ParseUint(fields[16], &cstime)) {
                            LOG_TO(SYSTEM, ERROR) << "Invalid proc data\n" << pidStat;
                            continue;
                        }
                        std::string proc = fields[1];
                        std::string name =
                            proc.length() > 2 ? proc.substr(1, proc.length() - 2) : "";
                        uint64_t user = utime + cutime;
                        uint64_t system = stime + cstime;
                        uint64_t totalUsage = user + system;

                        uint64_t diffUser = user - mPrevProcdata[pid].user;
                        uint64_t diffSystem = system - mPrevProcdata[pid].system;
                        uint64_t diffUsage = totalUsage - mPrevProcdata[pid].usage;

                        ProcData ldata;
                        ldata.user = user;
                        ldata.system = system;
                        ldata.usage = totalUsage;
                        procUsage[pid] = ldata;

                        float usageRatio = (float)(diffUsage * 100.0 / mDiffCpu);
                        if (cDebug && usageRatio > 100) {
                            LOG_TO(SYSTEM, INFO) << "pid: " << pid << " , ratio: " << usageRatio
                                                 << " , prev usage: " << mPrevProcdata[pid].usage
                                                 << " , cur usage: " << totalUsage
                                                 << " , total cpu diff: " << mDiffCpu;
                        }

                        ProcData data;
                        data.pid = pid;
                        data.name = name;
                        data.usageRatio = usageRatio;
                        data.user = diffUser;
                        data.system = diffSystem;
                        procList.push(data);
                    }
                }
            }
        }
        mPrevProcdata = std::move(procUsage);
        out->append(TOP_HEADER);
        for (uint32_t count = 0; !procList.empty() && count < mTopcount; count++) {
            ProcData data = procList.top();
            out->append(android::base::StringPrintf(FMT_TOP_PROFILE, data.usageRatio, data.pid,
                                                    data.name.c_str(), data.user, data.system));
            procList.pop();
        }
        closedir(dir);
    } else {
        LOG_TO(SYSTEM, ERROR) << "Fail to open /proc/";
    }
}

void CpuUsage::getOverallUsage(std::chrono::system_clock::time_point &now, std::string *out) {
    mDiffCpu = 0;
    mTotalRatio = 0.0f;
    std::string procStat;

    // Get overall cpu usage
    if (android::base::ReadFileToString("/proc/stat", &procStat)) {
        std::istringstream stream(procStat);
        std::string line;
        while (getline(stream, line)) {
            std::vector<std::string> fields = android::base::Split(line, " ");
            if (fields[0].find("cpu") != std::string::npos) {
                std::string cpuStr = fields[0];
                std::string core = cpuStr.length() > 3 ? cpuStr.substr(3, cpuStr.length() - 3) : "";
                uint64_t user = 0;
                uint64_t nice = 0;
                uint64_t system = 0;
                uint64_t idle = 0;
                uint64_t iowait = 0;
                uint64_t irq = 0;
                uint64_t softirq = 0;
                uint64_t steal = 0;

                // cpu  6013 3243 6311 92390 517 693 319 0 0 0  <-- (fields[1] = "")
                // cpu0 558 139 568 12135 67 121 50 0 0 0
                uint32_t base = core.compare("") ? 1 : 2;

                if (!base::ParseUint(fields[base], &user) ||
                    !base::ParseUint(fields[base + 1], &nice) ||
                    !base::ParseUint(fields[base + 2], &system) ||
                    !base::ParseUint(fields[base + 3], &idle) ||
                    !base::ParseUint(fields[base + 4], &iowait) ||
                    !base::ParseUint(fields[base + 5], &irq) ||
                    !base::ParseUint(fields[base + 6], &softirq) ||
                    !base::ParseUint(fields[base + 7], &steal)) {
                    LOG_TO(SYSTEM, ERROR) << "Invalid /proc/stat data\n" << line;
                    continue;
                }

                uint64_t cpuTime = user + nice + system + idle + iowait + irq + softirq + steal;
                uint64_t cpuUsage = cpuTime - idle - iowait;
                uint64_t userUsage = user + nice;

                if (!core.compare("")) {
                    uint64_t diffUsage = cpuUsage - mPrevUsage.cpuUsage;
                    mDiffCpu = cpuTime - mPrevUsage.cpuTime;
                    uint64_t diffUser = userUsage - mPrevUsage.userUsage;
                    uint64_t diffSys = system - mPrevUsage.sysUsage;
                    uint64_t diffIo = iowait - mPrevUsage.ioUsage;

                    mTotalRatio = (float)(diffUsage * 100.0 / mDiffCpu);
                    float userRatio = (float)(diffUser * 100.0 / mDiffCpu);
                    float sysRatio = (float)(diffSys * 100.0 / mDiffCpu);
                    float ioRatio = (float)(diffIo * 100.0 / mDiffCpu);

                    if (cDebug) {
                        LOG_TO(SYSTEM, INFO)
                            << "prev total: " << mPrevUsage.cpuUsage
                            << " , cur total: " << cpuUsage << " , diffusage: " << diffUsage
                            << " , diffcpu: " << mDiffCpu << " , ratio: " << mTotalRatio;
                    }

                    mPrevUsage.cpuUsage = cpuUsage;
                    mPrevUsage.cpuTime = cpuTime;
                    mPrevUsage.userUsage = userUsage;
                    mPrevUsage.sysUsage = system;
                    mPrevUsage.ioUsage = iowait;

                    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now - mLast);
                    out->append(android::base::StringPrintf(FMT_CPU_TOTAL, ms.count() / 1000,
                                                            ms.count() % 1000, mTotalRatio,
                                                            userRatio, sysRatio, ioRatio));
                } else {
                    // calculate total cpu usage of each core
                    uint32_t c = 0;
                    if (!base::ParseUint(core, &c)) {
                        LOG_TO(SYSTEM, ERROR) << "Invalid core: " << core;
                        continue;
                    }
                    uint64_t diffUsage = cpuUsage - mPrevCoresUsage[c].cpuUsage;
                    float coreTotalRatio = (float)(diffUsage * 100.0 / mDiffCpu);
                    if (cDebug) {
                        LOG_TO(SYSTEM, INFO)
                            << "core " << c << " , prev cpu usage: " << mPrevCoresUsage[c].cpuUsage
                            << " , cur cpu usage: " << cpuUsage << " , diffusage: " << diffUsage
                            << " , difftotalcpu: " << mDiffCpu << " , ratio: " << coreTotalRatio;
                    }
                    mPrevCoresUsage[c].cpuUsage = cpuUsage;

                    char buf[64];
                    sprintf(buf, "%.2f%%]", coreTotalRatio);
                    out->append("[" + core + ":" + std::string(buf));
                }
            }
        }
        out->append("\n");
    } else {
        LOG_TO(SYSTEM, ERROR) << "Fail to read /proc/stat";
    }
}

void CpuUsage::refresh(void) {
    if (mDisabled)
        return;

    std::string out;
    std::chrono::system_clock::time_point now = std::chrono::system_clock::now();

    getOverallUsage(now, &out);

    if (mTotalRatio >= mProfileThreshold) {
        if (cDebug)
            LOG_TO(SYSTEM, INFO) << "Total CPU usage over " << mProfileThreshold << "%";
        std::string profileResult;
        profileProcess(&profileResult);
        if (mProfileProcess) {
            // Dump top processes once met threshold continuously at least twice.
            out.append(profileResult);
        } else
            mProfileProcess = true;
    } else
        mProfileProcess = false;

    append(now, out);
    mLast = now;
    if (cDebug) {
        auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
            std::chrono::system_clock::now() - now);
        LOG_TO(SYSTEM, INFO) << "Took " << ms.count() << " ms, data bytes: " << out.length();
    }
}
