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

package com.android.internal.os;

import android.annotation.Nullable;
import android.os.Process;
import android.util.Slog;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;

import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.function.Predicate;

/**
 * Given a process, will iterate over the child threads of the process, and return the CPU usage
 * statistics for each child thread. The CPU usage statistics contain the amount of time spent in a
 * frequency band.
 *
 * <p>Frequencies are bucketed together to reduce the amount of data created. This means that we
 * return less frequencies than provided by {@link ProcTimeInStateReader}. The number of
 * frequencies is configurable by {@link #setNumBuckets}. Frequencies are reported as the lowest
 * frequency in that range. Frequencies are spread as evenly as possible across the buckets. The
 * buckets do not cross over the little/big frequencies reported.
 *
 * <p>N.B.: In order to bucket across little/big frequencies correctly, we assume that the {@code
 * time_in_state} file contains every little core frequency in ascending order, followed by every
 * big core frequency in ascending order. This assumption might not hold for devices with different
 * kernel implementations of the {@code time_in_state} file generation.
 */
public class KernelCpuThreadReader {

    private static final String TAG = "KernelCpuThreadReader";

    private static final boolean DEBUG = false;

    /**
     * The name of the file to read CPU statistics from, must be found in {@code
     * /proc/$PID/task/$TID}
     */
    private static final String CPU_STATISTICS_FILENAME = "time_in_state";

    /**
     * The name of the file to read process command line invocation from, must be found in
     * {@code /proc/$PID/}
     */
    private static final String PROCESS_NAME_FILENAME = "cmdline";

    /**
     * The name of the file to read thread name from, must be found in
     * {@code /proc/$PID/task/$TID}
     */
    private static final String THREAD_NAME_FILENAME = "comm";

    /**
     * Glob pattern for the process directory names under {@code proc}
     */
    private static final String PROCESS_DIRECTORY_FILTER = "[0-9]*";

    /**
     * Default process name when the name can't be read
     */
    private static final String DEFAULT_PROCESS_NAME = "unknown_process";

    /**
     * Default thread name when the name can't be read
     */
    private static final String DEFAULT_THREAD_NAME = "unknown_thread";

    /**
     * Default mount location of the {@code proc} filesystem
     */
    private static final Path DEFAULT_PROC_PATH = Paths.get("/proc");

    /**
     * The initial {@code time_in_state} file for {@link ProcTimeInStateReader}
     */
    private static final Path DEFAULT_INITIAL_TIME_IN_STATE_PATH =
            DEFAULT_PROC_PATH.resolve("self/time_in_state");

    /**
     * Value returned when there was an error getting an integer ID value (e.g. PID, UID)
     */
    private static final int ID_ERROR = -1;

    /**
     * When checking whether to report data for a thread, we check the UID of the thread's owner
     * against this predicate
     */
    private Predicate<Integer> mUidPredicate;

    /**
     * If a thread has strictly less than {@code minimumTotalCpuUsageMillis} total CPU usage, it
     * will not be reported
     */
    private int mMinimumTotalCpuUsageMillis;

    /**
     * Where the proc filesystem is mounted
     */
    private final Path mProcPath;

    /**
     * Frequencies read from the {@code time_in_state} file. Read from {@link
     * #mProcTimeInStateReader#getCpuFrequenciesKhz()} and cast to {@code int[]}
     */
    private int[] mFrequenciesKhz;

    /**
     * Used to read and parse {@code time_in_state} files
     */
    private final ProcTimeInStateReader mProcTimeInStateReader;

    /**
     * Used to sort frequencies and usage times into buckets
     */
    private FrequencyBucketCreator mFrequencyBucketCreator;

    private final Injector mInjector;

    /**
     * Create with a path where `proc` is mounted. Used primarily for testing
     *
     * @param procPath where `proc` is mounted (to find, see {@code mount | grep ^proc})
     * @param initialTimeInStatePath where the initial {@code time_in_state} file exists to define
     * format
     */
    @VisibleForTesting
    public KernelCpuThreadReader(
            int numBuckets,
            Predicate<Integer> uidPredicate,
            int minimumTotalCpuUsageMillis,
            Path procPath,
            Path initialTimeInStatePath,
            Injector injector) throws IOException {
        mUidPredicate = uidPredicate;
        mMinimumTotalCpuUsageMillis = minimumTotalCpuUsageMillis;
        mProcPath = procPath;
        mProcTimeInStateReader = new ProcTimeInStateReader(initialTimeInStatePath);
        mInjector = injector;
        setNumBuckets(numBuckets);
    }

    /**
     * Create the reader and handle exceptions during creation
     *
     * @return the reader, null if an exception was thrown during creation
     */
    @Nullable
    public static KernelCpuThreadReader create(
            int numBuckets, Predicate<Integer> uidPredicate, int minimumTotalCpuUsageMillis) {
        try {
            return new KernelCpuThreadReader(
                    numBuckets,
                    uidPredicate,
                    minimumTotalCpuUsageMillis,
                    DEFAULT_PROC_PATH,
                    DEFAULT_INITIAL_TIME_IN_STATE_PATH,
                    new Injector());
        } catch (IOException e) {
            Slog.e(TAG, "Failed to initialize KernelCpuThreadReader", e);
            return null;
        }
    }

    /**
     * Get the per-thread CPU usage of all processes belonging to a set of UIDs
     *
     * <p>This function will crawl through all process {@code proc} directories found by the pattern
     * {@code /proc/[0-9]*}, and then check the UID using {@code /proc/$PID/status}. This takes
     * approximately 500ms on a Pixel 2. Therefore, this method can be computationally expensive,
     * and should not be called more than once an hour.
     *
     * <p>Data is only collected for UIDs passing the predicate supplied in {@link
     * #setUidPredicate}.
     */
    @Nullable
    public ArrayList<ProcessCpuUsage> getProcessCpuUsageByUids() {
        if (DEBUG) {
            Slog.d(TAG, "Reading CPU thread usages for processes owned by UIDs");
        }

        final ArrayList<ProcessCpuUsage> processCpuUsages = new ArrayList<>();

        try (DirectoryStream<Path> processPaths =
                     Files.newDirectoryStream(mProcPath, PROCESS_DIRECTORY_FILTER)) {
            for (Path processPath : processPaths) {
                final int processId = getProcessId(processPath);
                final int uid = mInjector.getUidForPid(processId);
                if (uid == ID_ERROR || processId == ID_ERROR) {
                    continue;
                }
                if (!mUidPredicate.test(uid)) {
                    continue;
                }

                final ProcessCpuUsage processCpuUsage =
                        getProcessCpuUsage(processPath, processId, uid);
                if (processCpuUsage != null) {
                    processCpuUsages.add(processCpuUsage);
                }
            }
        } catch (IOException e) {
            Slog.w("Failed to iterate over process paths", e);
            return null;
        }

        if (processCpuUsages.isEmpty()) {
            Slog.w(TAG, "Didn't successfully get any process CPU information for UIDs specified");
            return null;
        }

        if (DEBUG) {
            Slog.d(TAG, "Read usage for " + processCpuUsages.size() + " processes");
        }

        return processCpuUsages;
    }

    /**
     * Read all of the CPU usage statistics for each child thread of the current process
     *
     * @return process CPU usage containing usage of all child threads
     */
    @Nullable
    public ProcessCpuUsage getCurrentProcessCpuUsage() {
        return getProcessCpuUsage(mProcPath.resolve("self"), mInjector.myPid(), mInjector.myUid());
    }

    /**
     * Read all of the CPU usage statistics for each child thread of a process
     *
     * @param processPath the {@code /proc} path of the thread
     * @param processId the ID of the process
     * @param uid the ID of the user who owns the process
     * @return process CPU usage containing usage of all child threads. Null if the process exited
     * and its {@code proc} directory was removed while collecting information
     */
    @Nullable
    private ProcessCpuUsage getProcessCpuUsage(Path processPath, int processId, int uid) {
        if (DEBUG) {
            Slog.d(TAG, "Reading CPU thread usages with directory " + processPath
                    + " process ID " + processId
                    + " and user ID " + uid);
        }

        final Path allThreadsPath = processPath.resolve("task");
        final ArrayList<ThreadCpuUsage> threadCpuUsages = new ArrayList<>();
        try (DirectoryStream<Path> threadPaths = Files.newDirectoryStream(allThreadsPath)) {
            for (Path threadDirectory : threadPaths) {
                ThreadCpuUsage threadCpuUsage = getThreadCpuUsage(threadDirectory);
                if (threadCpuUsage != null) {
                    threadCpuUsages.add(threadCpuUsage);
                }
            }
        } catch (IOException e) {
            // Expected when a process finishes
            return null;
        }

        // If we found no threads, then the process has exited while we were reading from it
        if (threadCpuUsages.isEmpty()) {
            return null;
        }

        if (DEBUG) {
            Slog.d(TAG, "Read CPU usage of " + threadCpuUsages.size() + " threads");
        }
        return new ProcessCpuUsage(
                processId,
                getProcessName(processPath),
                uid,
                threadCpuUsages);
    }

    /**
     * Set the number of frequency buckets to use
     */
    void setNumBuckets(int numBuckets) {
        if (numBuckets < 1) {
            Slog.w(TAG, "Number of buckets must be at least 1, but was " + numBuckets);
            return;
        }
        // If `numBuckets` hasn't changed since the last set, do nothing
        if (mFrequenciesKhz != null && mFrequenciesKhz.length == numBuckets) {
            return;
        }
        mFrequencyBucketCreator = new FrequencyBucketCreator(
                mProcTimeInStateReader.getFrequenciesKhz(), numBuckets);
        mFrequenciesKhz = mFrequencyBucketCreator.getBucketMinFrequencies(
                mProcTimeInStateReader.getFrequenciesKhz());
    }

    /**
     * Set the UID predicate for {@link #getProcessCpuUsageByUids}
     */
    void setUidPredicate(Predicate<Integer> uidPredicate) {
        mUidPredicate = uidPredicate;
    }

    /**
     * If a thread has strictly less than {@code minimumTotalCpuUsageMillis} total CPU usage, it
     * will not be reported
     */
    void setMinimumTotalCpuUsageMillis(int minimumTotalCpuUsageMillis) {
        if (minimumTotalCpuUsageMillis < 0) {
            Slog.w(TAG, "Negative minimumTotalCpuUsageMillis: " + minimumTotalCpuUsageMillis);
            return;
        }
        mMinimumTotalCpuUsageMillis = minimumTotalCpuUsageMillis;
    }

    /**
     * Get the CPU frequencies that correspond to the times reported in
     * {@link ThreadCpuUsage#usageTimesMillis}
     */
    @Nullable
    public int[] getCpuFrequenciesKhz() {
        return mFrequenciesKhz;
    }

    /**
     * Get a thread's CPU usage
     *
     * @param threadDirectory the {@code /proc} directory of the thread
     * @return thread CPU usage. Null if the thread exited and its {@code proc} directory was
     * removed while collecting information
     */
    @Nullable
    private ThreadCpuUsage getThreadCpuUsage(Path threadDirectory) {
        // Get the thread ID from the directory name
        final int threadId;
        try {
            final String directoryName = threadDirectory.getFileName().toString();
            threadId = Integer.parseInt(directoryName);
        } catch (NumberFormatException e) {
            Slog.w(TAG, "Failed to parse thread ID when iterating over /proc/*/task", e);
            return null;
        }

        // Get the thread name from the thread directory
        final String threadName = getThreadName(threadDirectory);

        // Get the CPU statistics from the directory
        final Path threadCpuStatPath = threadDirectory.resolve(CPU_STATISTICS_FILENAME);
        final long[] cpuUsagesLong = mProcTimeInStateReader.getUsageTimesMillis(threadCpuStatPath);
        if (cpuUsagesLong == null) {
            return null;
        }
        int[] cpuUsages = mFrequencyBucketCreator.getBucketedValues(cpuUsagesLong);

        // Check if the total CPU usage below the threshold
        int totalCpuUsage = 0;
        for (int i = 0; i < cpuUsages.length; i++) {
            totalCpuUsage += cpuUsages[i];
        }
        if (totalCpuUsage < mMinimumTotalCpuUsageMillis) {
            return null;
        }

        return new ThreadCpuUsage(threadId, threadName, cpuUsages);
    }

    /**
     * Get the command used to start a process
     */
    private String getProcessName(Path processPath) {
        final Path processNamePath = processPath.resolve(PROCESS_NAME_FILENAME);

        final String processName =
                ProcStatsUtil.readSingleLineProcFile(processNamePath.toString());
        if (processName != null) {
            return processName;
        }
        return DEFAULT_PROCESS_NAME;
    }

    /**
     * Get the name of a thread, given the {@code /proc} path of the thread
     */
    private String getThreadName(Path threadPath) {
        final Path threadNamePath = threadPath.resolve(THREAD_NAME_FILENAME);
        final String threadName =
                ProcStatsUtil.readNullSeparatedFile(threadNamePath.toString());
        if (threadName == null) {
            return DEFAULT_THREAD_NAME;
        }
        return threadName;
    }

    /**
     * Get the ID of a process from its path
     *
     * @param processPath {@code proc} path of the process
     * @return the ID, {@link #ID_ERROR} if the path could not be parsed
     */
    private int getProcessId(Path processPath) {
        String fileName = processPath.getFileName().toString();
        try {
            return Integer.parseInt(fileName);
        } catch (NumberFormatException e) {
            Slog.w(TAG, "Failed to parse " + fileName + " as process ID", e);
            return ID_ERROR;
        }
    }

    /**
     * Puts frequencies and usage times into buckets
     */
    @VisibleForTesting
    public static class FrequencyBucketCreator {
        private final int mNumBuckets;
        private final int mNumFrequencies;
        private final int mBigFrequenciesStartIndex;
        private final int mLittleNumBuckets;
        private final int mBigNumBuckets;
        private final int mLittleBucketSize;
        private final int mBigBucketSize;

        /**
         * Buckets based of a list of frequencies
         *
         * @param frequencies the frequencies to base buckets off
         * @param numBuckets how many buckets to create
         */
        @VisibleForTesting
        public FrequencyBucketCreator(long[] frequencies, int numBuckets) {
            Preconditions.checkArgument(numBuckets > 0);

            mNumFrequencies = frequencies.length;
            mBigFrequenciesStartIndex = getBigFrequenciesStartIndex(frequencies);

            final int littleNumBuckets;
            final int bigNumBuckets;
            if (mBigFrequenciesStartIndex < frequencies.length) {
                littleNumBuckets = numBuckets / 2;
                bigNumBuckets = numBuckets - littleNumBuckets;
            } else {
                // If we've got no big frequencies, set all buckets to little frequencies
                littleNumBuckets = numBuckets;
                bigNumBuckets = 0;
            }

            // Ensure that we don't have more buckets than frequencies
            mLittleNumBuckets = Math.min(littleNumBuckets, mBigFrequenciesStartIndex);
            mBigNumBuckets = Math.min(
                    bigNumBuckets, frequencies.length - mBigFrequenciesStartIndex);
            mNumBuckets = mLittleNumBuckets + mBigNumBuckets;

            // Set the size of each little and big bucket. If they have no buckets, the size is zero
            mLittleBucketSize = mLittleNumBuckets == 0 ? 0 :
                    mBigFrequenciesStartIndex / mLittleNumBuckets;
            mBigBucketSize = mBigNumBuckets == 0 ? 0 :
                    (frequencies.length - mBigFrequenciesStartIndex) / mBigNumBuckets;
        }

        /**
         * Find the index where frequencies change from little core to big core
         */
        @VisibleForTesting
        public static int getBigFrequenciesStartIndex(long[] frequenciesKhz) {
            for (int i = 0; i < frequenciesKhz.length - 1; i++) {
                if (frequenciesKhz[i] > frequenciesKhz[i + 1]) {
                    return i + 1;
                }
            }

            return frequenciesKhz.length;
        }

        /**
         * Get the minimum frequency in each bucket
         */
        @VisibleForTesting
        public int[] getBucketMinFrequencies(long[] frequenciesKhz) {
            Preconditions.checkArgument(frequenciesKhz.length == mNumFrequencies);
            // If there's only one bucket, we bucket everything together so the first bucket is the
            // min frequency
            if (mNumBuckets == 1) {
                return new int[]{(int) frequenciesKhz[0]};
            }

            final int[] bucketMinFrequencies = new int[mNumBuckets];
            // Initialize little buckets min frequencies
            for (int i = 0; i < mLittleNumBuckets; i++) {
                bucketMinFrequencies[i] = (int) frequenciesKhz[i * mLittleBucketSize];
            }
            // Initialize big buckets min frequencies
            for (int i = 0; i < mBigNumBuckets; i++) {
                final int frequencyIndex = mBigFrequenciesStartIndex + i * mBigBucketSize;
                bucketMinFrequencies[mLittleNumBuckets + i] = (int) frequenciesKhz[frequencyIndex];
            }
            return bucketMinFrequencies;
        }

        /**
         * Put an array of values into buckets. This takes a {@code long[]} and returns {@code
         * int[]} as everywhere this method is used will have to do the conversion anyway, so we
         * save time by doing it here instead
         *
         * @param values the values to bucket
         * @return the bucketed usage times
         */
        @VisibleForTesting
        public int[] getBucketedValues(long[] values) {
            Preconditions.checkArgument(values.length == mNumFrequencies);
            final int[] bucketed = new int[mNumBuckets];

            // If there's only one bucket, add all frequencies in
            if (mNumBuckets == 1) {
                for (int i = 0; i < values.length; i++) {
                    bucketed[0] += values[i];
                }
                return bucketed;
            }

            // Initialize the little buckets
            for (int i = 0; i < mBigFrequenciesStartIndex; i++) {
                final int bucketIndex = Math.min(i / mLittleBucketSize, mLittleNumBuckets - 1);
                bucketed[bucketIndex] += values[i];
            }
            // Initialize the big buckets
            for (int i = mBigFrequenciesStartIndex; i < values.length; i++) {
                final int bucketIndex = Math.min(
                        mLittleNumBuckets + (i - mBigFrequenciesStartIndex) / mBigBucketSize,
                        mNumBuckets - 1);
                bucketed[bucketIndex] += values[i];
            }
            return bucketed;
        }
    }

    /**
     * CPU usage of a process
     */
    public static class ProcessCpuUsage {
        public final int processId;
        public final String processName;
        public final int uid;
        public final ArrayList<ThreadCpuUsage> threadCpuUsages;

        ProcessCpuUsage(
                int processId,
                String processName,
                int uid,
                ArrayList<ThreadCpuUsage> threadCpuUsages) {
            this.processId = processId;
            this.processName = processName;
            this.uid = uid;
            this.threadCpuUsages = threadCpuUsages;
        }
    }

    /**
     * CPU usage of a thread
     */
    public static class ThreadCpuUsage {
        public final int threadId;
        public final String threadName;
        public final int[] usageTimesMillis;

        ThreadCpuUsage(
                int threadId,
                String threadName,
                int[] usageTimesMillis) {
            this.threadId = threadId;
            this.threadName = threadName;
            this.usageTimesMillis = usageTimesMillis;
        }
    }

    /**
     * Used to inject static methods from {@link Process}
     */
    @VisibleForTesting
    public static class Injector {
        /**
         * Get the PID of the current process
         */
        public int myPid() {
            return Process.myPid();
        }

        /**
         * Get the UID that owns the current process
         */
        public int myUid() {
            return Process.myUid();
        }

        /**
         * Get the UID for the process with ID {@code pid}
         */
        public int getUidForPid(int pid) {
            return Process.getUidForPid(pid);
        }
    }
}
