/*
 * Copyright (C) 2020 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.
 */

#include "core_jni_helpers.h"

#include <cputimeinstate.h>
#include <dirent.h>

#include <android-base/file.h>
#include <android-base/parseint.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android_runtime/Log.h>

#include <nativehelper/ScopedPrimitiveArray.h>

namespace android {

static constexpr uint16_t DEFAULT_THREAD_AGGREGATION_KEY = 0;
static constexpr uint16_t SELECTED_THREAD_AGGREGATION_KEY = 1;

static constexpr uint64_t NSEC_PER_MSEC = 1000000;

// Number of milliseconds in a jiffy - the unit of time measurement for processes and threads
static const uint32_t gJiffyMillis = (uint32_t)(1000 / sysconf(_SC_CLK_TCK));

// Abstract class for readers of CPU time-in-state. There are two implementations of
// this class: BpfCpuTimeInStateReader and MockCpuTimeInStateReader.  The former is used
// by the production code. The latter is used by unit tests to provide mock
// CPU time-in-state data via a Java implementation.
class ICpuTimeInStateReader {
public:
    virtual ~ICpuTimeInStateReader() {}

    // Returns the overall number of cluser-frequency combinations
    virtual size_t getCpuFrequencyCount();

    // Marks the CPU time-in-state tracking for threads of the specified TGID
    virtual bool startTrackingProcessCpuTimes(pid_t) = 0;

    // Marks the thread specified by its PID for CPU time-in-state tracking.
    virtual bool startAggregatingTaskCpuTimes(pid_t, uint16_t) = 0;

    // Retrieves the accumulated time-in-state data, which is organized as a map
    // from aggregation keys to vectors of vectors using the format:
    // { aggKey0 -> [[t0_0_0, t0_0_1, ...], [t0_1_0, t0_1_1, ...], ...],
    //   aggKey1 -> [[t1_0_0, t1_0_1, ...], [t1_1_0, t1_1_1, ...], ...], ... }
    // where ti_j_k is the ns tid i spent running on the jth cluster at the cluster's kth lowest
    // freq.
    virtual std::optional<std::unordered_map<uint16_t, std::vector<std::vector<uint64_t>>>>
    getAggregatedTaskCpuFreqTimes(pid_t, const std::vector<uint16_t> &);
};

// ICpuTimeInStateReader that uses eBPF to provide a map of aggregated CPU time-in-state values.
// See cputtimeinstate.h/.cpp
class BpfCpuTimeInStateReader : public ICpuTimeInStateReader {
public:
    size_t getCpuFrequencyCount() {
        std::optional<std::vector<std::vector<uint32_t>>> cpuFreqs = android::bpf::getCpuFreqs();
        if (!cpuFreqs) {
            ALOGE("Cannot obtain CPU frequency count");
            return 0;
        }

        size_t freqCount = 0;
        for (auto cluster : *cpuFreqs) {
            freqCount += cluster.size();
        }

        return freqCount;
    }

    bool startTrackingProcessCpuTimes(pid_t tgid) {
        return android::bpf::startTrackingProcessCpuTimes(tgid);
    }

    bool startAggregatingTaskCpuTimes(pid_t pid, uint16_t aggregationKey) {
        return android::bpf::startAggregatingTaskCpuTimes(pid, aggregationKey);
    }

    std::optional<std::unordered_map<uint16_t, std::vector<std::vector<uint64_t>>>>
    getAggregatedTaskCpuFreqTimes(pid_t pid, const std::vector<uint16_t> &aggregationKeys) {
        return android::bpf::getAggregatedTaskCpuFreqTimes(pid, aggregationKeys);
    }
};

// ICpuTimeInStateReader that uses JNI to provide a map of aggregated CPU time-in-state
// values.
// This version of CpuTimeInStateReader is used exclusively for providing mock data in tests.
class MockCpuTimeInStateReader : public ICpuTimeInStateReader {
private:
    JNIEnv *mEnv;
    jobject mCpuTimeInStateReader;

public:
    MockCpuTimeInStateReader(JNIEnv *env, jobject cpuTimeInStateReader)
          : mEnv(env), mCpuTimeInStateReader(cpuTimeInStateReader) {}

    size_t getCpuFrequencyCount();

    bool startTrackingProcessCpuTimes(pid_t tgid);

    bool startAggregatingTaskCpuTimes(pid_t pid, uint16_t aggregationKey);

    std::optional<std::unordered_map<uint16_t, std::vector<std::vector<uint64_t>>>>
    getAggregatedTaskCpuFreqTimes(pid_t tgid, const std::vector<uint16_t> &aggregationKeys);
};

static ICpuTimeInStateReader *getCpuTimeInStateReader(JNIEnv *env,
                                                      jobject cpuTimeInStateReaderObject) {
    if (cpuTimeInStateReaderObject) {
        return new MockCpuTimeInStateReader(env, cpuTimeInStateReaderObject);
    } else {
        return new BpfCpuTimeInStateReader();
    }
}

static jint getCpuFrequencyCount(JNIEnv *env, jclass, jobject cpuTimeInStateReaderObject) {
    std::unique_ptr<ICpuTimeInStateReader> cpuTimeInStateReader(
            getCpuTimeInStateReader(env, cpuTimeInStateReaderObject));
    return cpuTimeInStateReader->getCpuFrequencyCount();
}

static jboolean startTrackingProcessCpuTimes(JNIEnv *env, jclass, jint tgid,
                                             jobject cpuTimeInStateReaderObject) {
    std::unique_ptr<ICpuTimeInStateReader> cpuTimeInStateReader(
            getCpuTimeInStateReader(env, cpuTimeInStateReaderObject));
    return cpuTimeInStateReader->startTrackingProcessCpuTimes(tgid);
}

static jboolean startAggregatingThreadCpuTimes(JNIEnv *env, jclass, jintArray selectedThreadIdArray,
                                               jobject cpuTimeInStateReaderObject) {
    ScopedIntArrayRO selectedThreadIds(env, selectedThreadIdArray);
    std::unique_ptr<ICpuTimeInStateReader> cpuTimeInStateReader(
            getCpuTimeInStateReader(env, cpuTimeInStateReaderObject));

    for (int i = 0; i < selectedThreadIds.size(); i++) {
        if (!cpuTimeInStateReader->startAggregatingTaskCpuTimes(selectedThreadIds[i],
                                                                SELECTED_THREAD_AGGREGATION_KEY)) {
            return false;
        }
    }
    return true;
}

// Converts time-in-state data from a vector of vectors to a flat array.
// Also converts from nanoseconds to milliseconds.
static bool flattenTimeInStateData(ScopedLongArrayRW &cpuTimesMillis,
                                   const std::vector<std::vector<uint64_t>> &data) {
    size_t frequencyCount = cpuTimesMillis.size();
    size_t index = 0;
    for (const auto &cluster : data) {
        for (const uint64_t &timeNanos : cluster) {
            if (index < frequencyCount) {
                cpuTimesMillis[index] = timeNanos / NSEC_PER_MSEC;
            }
            index++;
        }
    }
    if (index != frequencyCount) {
        ALOGE("CPU time-in-state reader returned data for %zu frequencies; expected: %zu", index,
              frequencyCount);
        return false;
    }

    return true;
}

// Reads all CPU time-in-state data accumulated by BPF and aggregates per-frequency
// time in state data for all threads.  Also, separately aggregates time in state for
// selected threads whose TIDs are passes as selectedThreadIds.
static jboolean readProcessCpuUsage(JNIEnv *env, jclass, jint pid,
                                    jlongArray threadCpuTimesMillisArray,
                                    jlongArray selectedThreadCpuTimesMillisArray,
                                    jobject cpuTimeInStateReaderObject) {
    ScopedLongArrayRW threadCpuTimesMillis(env, threadCpuTimesMillisArray);
    ScopedLongArrayRW selectedThreadCpuTimesMillis(env, selectedThreadCpuTimesMillisArray);
    std::unique_ptr<ICpuTimeInStateReader> cpuTimeInStateReader(
            getCpuTimeInStateReader(env, cpuTimeInStateReaderObject));

    const size_t frequencyCount = cpuTimeInStateReader->getCpuFrequencyCount();

    if (threadCpuTimesMillis.size() != frequencyCount) {
        ALOGE("Invalid threadCpuTimesMillis array length: %zu frequencies; expected: %zu",
              threadCpuTimesMillis.size(), frequencyCount);
        return false;
    }

    if (selectedThreadCpuTimesMillis.size() != frequencyCount) {
        ALOGE("Invalid selectedThreadCpuTimesMillis array length: %zu frequencies; expected: %zu",
              selectedThreadCpuTimesMillis.size(), frequencyCount);
        return false;
    }

    for (size_t i = 0; i < frequencyCount; i++) {
        threadCpuTimesMillis[i] = 0;
        selectedThreadCpuTimesMillis[i] = 0;
    }

    std::optional<std::unordered_map<uint16_t, std::vector<std::vector<uint64_t>>>> data =
            cpuTimeInStateReader->getAggregatedTaskCpuFreqTimes(pid,
                                                                {DEFAULT_THREAD_AGGREGATION_KEY,
                                                                 SELECTED_THREAD_AGGREGATION_KEY});
    if (!data) {
        ALOGE("Cannot read thread CPU times for PID %d", pid);
        return false;
    }

    if (!flattenTimeInStateData(threadCpuTimesMillis, (*data)[DEFAULT_THREAD_AGGREGATION_KEY])) {
        return false;
    }

    if (!flattenTimeInStateData(selectedThreadCpuTimesMillis,
                                (*data)[SELECTED_THREAD_AGGREGATION_KEY])) {
        return false;
    }

    // threadCpuTimesMillis returns CPU times for _all_ threads, including the selected ones
    for (size_t i = 0; i < frequencyCount; i++) {
        threadCpuTimesMillis[i] += selectedThreadCpuTimesMillis[i];
    }

    return true;
}

static const JNINativeMethod g_single_methods[] = {
        {"getCpuFrequencyCount",
         "(Lcom/android/internal/os/KernelSingleProcessCpuThreadReader$CpuTimeInStateReader;)I",
         (void *)getCpuFrequencyCount},
        {"startTrackingProcessCpuTimes",
         "(ILcom/android/internal/os/KernelSingleProcessCpuThreadReader$CpuTimeInStateReader;)Z",
         (void *)startTrackingProcessCpuTimes},
        {"startAggregatingThreadCpuTimes",
         "([ILcom/android/internal/os/KernelSingleProcessCpuThreadReader$CpuTimeInStateReader;)Z",
         (void *)startAggregatingThreadCpuTimes},
        {"readProcessCpuUsage",
         "(I[J[J"
         "Lcom/android/internal/os/KernelSingleProcessCpuThreadReader$CpuTimeInStateReader;)Z",
         (void *)readProcessCpuUsage},
};

int register_com_android_internal_os_KernelSingleProcessCpuThreadReader(JNIEnv *env) {
    return RegisterMethodsOrDie(env, "com/android/internal/os/KernelSingleProcessCpuThreadReader",
                                g_single_methods, NELEM(g_single_methods));
}

size_t MockCpuTimeInStateReader::getCpuFrequencyCount() {
    jclass cls = mEnv->GetObjectClass(mCpuTimeInStateReader);
    jmethodID mid = mEnv->GetMethodID(cls, "getCpuFrequencyCount", "()I");
    if (mid == 0) {
        ALOGE("Couldn't find the method getCpuFrequencyCount");
        return false;
    }
    return (size_t)mEnv->CallIntMethod(mCpuTimeInStateReader, mid);
}

bool MockCpuTimeInStateReader::startTrackingProcessCpuTimes(pid_t tgid) {
    jclass cls = mEnv->GetObjectClass(mCpuTimeInStateReader);
    jmethodID mid = mEnv->GetMethodID(cls, "startTrackingProcessCpuTimes", "(I)Z");
    if (mid == 0) {
        ALOGE("Couldn't find the method startTrackingProcessCpuTimes");
        return false;
    }
    return mEnv->CallBooleanMethod(mCpuTimeInStateReader, mid, tgid);
}

bool MockCpuTimeInStateReader::startAggregatingTaskCpuTimes(pid_t pid, uint16_t aggregationKey) {
    jclass cls = mEnv->GetObjectClass(mCpuTimeInStateReader);
    jmethodID mid = mEnv->GetMethodID(cls, "startAggregatingTaskCpuTimes", "(II)Z");
    if (mid == 0) {
        ALOGE("Couldn't find the method startAggregatingTaskCpuTimes");
        return false;
    }
    return mEnv->CallBooleanMethod(mCpuTimeInStateReader, mid, pid, aggregationKey);
}

std::optional<std::unordered_map<uint16_t, std::vector<std::vector<uint64_t>>>>
MockCpuTimeInStateReader::getAggregatedTaskCpuFreqTimes(
        pid_t pid, const std::vector<uint16_t> &aggregationKeys) {
    jclass cls = mEnv->GetObjectClass(mCpuTimeInStateReader);
    jmethodID mid =
            mEnv->GetMethodID(cls, "getAggregatedTaskCpuFreqTimes", "(I)[Ljava/lang/String;");
    if (mid == 0) {
        ALOGE("Couldn't find the method getAggregatedTaskCpuFreqTimes");
        return {};
    }

    std::unordered_map<uint16_t, std::vector<std::vector<uint64_t>>> map;

    jobjectArray stringArray =
            (jobjectArray)mEnv->CallObjectMethod(mCpuTimeInStateReader, mid, pid);
    int size = mEnv->GetArrayLength(stringArray);
    for (int i = 0; i < size; i++) {
        ScopedUtfChars line(mEnv, (jstring)mEnv->GetObjectArrayElement(stringArray, i));
        uint16_t aggregationKey;
        std::vector<std::vector<uint64_t>> times;

        // Each string is formatted like this: "aggKey:t0_0 t0_1...:t1_0 t1_1..."
        auto fields = android::base::Split(line.c_str(), ":");
        android::base::ParseUint(fields[0], &aggregationKey);

        for (int j = 1; j < fields.size(); j++) {
            auto numbers = android::base::Split(fields[j], " ");

            std::vector<uint64_t> chunk;
            for (int k = 0; k < numbers.size(); k++) {
                uint64_t time;
                android::base::ParseUint(numbers[k], &time);
                chunk.emplace_back(time);
            }
            times.emplace_back(chunk);
        }

        map.emplace(aggregationKey, times);
    }

    return map;
}

} // namespace android
