/*
 * 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 static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.testng.Assert.assertThrows;

import android.content.Context;
import android.os.FileUtils;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.function.Predicate;

@SmallTest
@RunWith(AndroidJUnit4.class)
public class KernelCpuThreadReaderTest {

    private static final int UID = 1000;
    private static final int PROCESS_ID = 1234;
    private static final int[] THREAD_IDS = {0, 1000, 1235, 4321};
    private static final String PROCESS_NAME = "test_process";
    private static final String[] THREAD_NAMES = {
            "test_thread_1", "test_thread_2", "test_thread_3", "test_thread_4"
    };
    private static final int[] THREAD_CPU_FREQUENCIES = {
            1000, 2000, 3000, 4000,
    };
    private static final int[][] THREAD_CPU_TIMES = {
            {1, 0, 0, 1},
            {0, 0, 0, 0},
            {1000, 1000, 1000, 1000},
            {0, 1, 2, 3},
    };

    private File mProcDirectory;

    @Before
    public void setUp() {
        Context context = InstrumentationRegistry.getContext();
        mProcDirectory = context.getDir("proc", Context.MODE_PRIVATE);
    }

    @After
    public void tearDown() throws Exception {
        FileUtils.deleteContents(mProcDirectory);
    }

    @Test
    public void testReader_currentProcess() throws IOException {
        KernelCpuThreadReader.Injector processUtils =
                new KernelCpuThreadReader.Injector() {
                    @Override
                    public int myPid() {
                        return PROCESS_ID;
                    }

                    @Override
                    public int myUid() {
                        return UID;
                    }

                    @Override
                    public int getUidForPid(int pid) {
                        return 0;
                    }
                };
        setupDirectory(mProcDirectory.toPath().resolve("self"), THREAD_IDS, PROCESS_NAME,
                THREAD_NAMES, THREAD_CPU_FREQUENCIES, THREAD_CPU_TIMES);

        final KernelCpuThreadReader kernelCpuThreadReader = new KernelCpuThreadReader(
                8,
                uid -> 1000 <= uid && uid < 2000,
                0,
                mProcDirectory.toPath(),
                mProcDirectory.toPath().resolve("self/task/" + THREAD_IDS[0] + "/time_in_state"),
                processUtils);
        final KernelCpuThreadReader.ProcessCpuUsage processCpuUsage =
                kernelCpuThreadReader.getCurrentProcessCpuUsage();
        checkResults(processCpuUsage, kernelCpuThreadReader.getCpuFrequenciesKhz(), UID, PROCESS_ID,
                THREAD_IDS, PROCESS_NAME, THREAD_NAMES, THREAD_CPU_FREQUENCIES, THREAD_CPU_TIMES);
    }

    @Test
    public void testReader_byUids() throws IOException {
        int[] uids = new int[]{0, 2, 3, 4, 5, 6000};
        Predicate<Integer> uidPredicate = uid -> uid == 0 || uid >= 4;
        int[] expectedUids = new int[]{0, 4, 5, 6000};
        KernelCpuThreadReader.Injector processUtils =
                new KernelCpuThreadReader.Injector() {
                    @Override
                    public int myPid() {
                        return 0;
                    }

                    @Override
                    public int myUid() {
                        return 0;
                    }

                    @Override
                    public int getUidForPid(int pid) {
                        return pid;
                    }
                };

        for (int uid : uids) {
            setupDirectory(mProcDirectory.toPath().resolve(String.valueOf(uid)),
                    new int[]{uid * 10},
                    "process" + uid, new String[]{"thread" + uid}, new int[]{1000},
                    new int[][]{{uid}});
        }
        final KernelCpuThreadReader kernelCpuThreadReader = new KernelCpuThreadReader(
                8,
                uidPredicate,
                0,
                mProcDirectory.toPath(),
                mProcDirectory.toPath().resolve(uids[0] + "/task/" + uids[0] + "/time_in_state"),
                processUtils);
        ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsageByUids =
                kernelCpuThreadReader.getProcessCpuUsageByUids();
        processCpuUsageByUids.sort(Comparator.comparing(usage -> usage.processId));

        assertEquals(expectedUids.length, processCpuUsageByUids.size());
        for (int i = 0; i < expectedUids.length; i++) {
            KernelCpuThreadReader.ProcessCpuUsage processCpuUsage =
                    processCpuUsageByUids.get(i);
            int uid = expectedUids[i];
            checkResults(processCpuUsage, kernelCpuThreadReader.getCpuFrequenciesKhz(),
                    uid, uid, new int[]{uid * 10}, "process" + uid, new String[]{"thread" + uid},
                    new int[]{1000}, new int[][]{{uid}});
        }
    }

    @Test
    public void testReader_filtersLowUsage() throws IOException {
        int[] uids = new int[]{0, 1, 2, 3, 4};
        int[] cpuUsage = new int[]{10, 0, 2, 100, 3};
        int[] expectedUids = new int[]{0, 3, 4};
        Predicate<Integer> uidPredicate = uid -> true;
        KernelCpuThreadReader.Injector processUtils =
                new KernelCpuThreadReader.Injector() {
                    @Override
                    public int myPid() {
                        return 0;
                    }

                    @Override
                    public int myUid() {
                        return 0;
                    }

                    @Override
                    public int getUidForPid(int pid) {
                        return pid;
                    }
                };

        for (int i = 0; i < uids.length; i++) {
            int uid = uids[i];
            setupDirectory(
                    mProcDirectory.toPath().resolve(String.valueOf(uid)),
                    new int[]{uid * 10},
                    "process" + uid,
                    new String[]{"thread" + uid},
                    new int[]{1000},
                    new int[][]{{cpuUsage[i]}});
        }
        final KernelCpuThreadReader kernelCpuThreadReader = new KernelCpuThreadReader(
                8,
                uidPredicate,
                30,
                mProcDirectory.toPath(),
                mProcDirectory.toPath().resolve(uids[0] + "/task/" + uids[0] + "/time_in_state"),
                processUtils);
        ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsageByUids =
                kernelCpuThreadReader.getProcessCpuUsageByUids();
        processCpuUsageByUids.sort(Comparator.comparing(usage -> usage.uid));

        assertEquals(expectedUids.length, processCpuUsageByUids.size());
        for (int i = 0; i < expectedUids.length; i++) {
            KernelCpuThreadReader.ProcessCpuUsage processCpuUsage =
                    processCpuUsageByUids.get(i);
            assertEquals(expectedUids[i], processCpuUsage.uid);
        }

    }

    @Test
    public void testReader_otherThreads() throws IOException {
        final Path processPath = mProcDirectory.toPath().resolve("self");
        setupDirectory(
                processPath,
                new int[]{1, 2, 3},
                "process",
                new String[]{"thread1", "thread2", "thread3"},
                new int[]{1000, 2000},
                new int[][]{{0, 100}, {10, 0}, {0, 300}});
        final KernelCpuThreadReader kernelCpuThreadReader = new KernelCpuThreadReader(
                8,
                i -> true,
                2000,
                mProcDirectory.toPath(),
                processPath.resolve("task/1/time_in_state"),
                new KernelCpuThreadReader.Injector() {
                    @Override
                    public int myPid() {
                        return 1000;
                    }

                    @Override
                    public int myUid() {
                        return 0;
                    }

                    @Override
                    public int getUidForPid(int pid) {
                        return 0;
                    }
                });
        checkResults(
                kernelCpuThreadReader.getCurrentProcessCpuUsage(),
                kernelCpuThreadReader.getCpuFrequenciesKhz(),
                0,
                1000,
                new int[]{-1, 3},
                "process",
                new String[]{"__OTHER_THREADS", "thread3"},
                new int[]{1000, 2000},
                new int[][]{{100, 1000}, {0, 3000}}
        );
    }

    private void setupDirectory(Path processPath, int[] threadIds, String processName,
            String[] threadNames, int[] cpuFrequencies, int[][] cpuTimes) throws IOException {
        // Make /proc/$PID
        assertTrue(processPath.toFile().mkdirs());

        // Make /proc/$PID/task
        final Path selfThreadsPath = processPath.resolve("task");
        assertTrue(selfThreadsPath.toFile().mkdirs());

        // Make /proc/$PID/cmdline
        Files.write(processPath.resolve("cmdline"), processName.getBytes());

        // Make thread directories in reverse order, as they are read in order of creation by
        // CpuThreadProcReader
        for (int i = 0; i < threadIds.length; i++) {
            // Make /proc/$PID/task/$TID
            final Path threadPath = selfThreadsPath.resolve(String.valueOf(threadIds[i]));
            assertTrue(threadPath.toFile().mkdirs());

            // Make /proc/$PID/task/$TID/comm
            Files.write(threadPath.resolve("comm"), threadNames[i].getBytes());

            // Make /proc/$PID/task/$TID/time_in_state
            final OutputStream timeInStateStream =
                    Files.newOutputStream(threadPath.resolve("time_in_state"));
            for (int j = 0; j < cpuFrequencies.length; j++) {
                final String line = String.valueOf(cpuFrequencies[j]) + " "
                        + String.valueOf(cpuTimes[i][j]) + "\n";
                timeInStateStream.write(line.getBytes());
            }
            timeInStateStream.close();
        }
    }

    private void checkResults(KernelCpuThreadReader.ProcessCpuUsage processCpuUsage,
            int[] readerCpuFrequencies, int uid, int processId, int[] threadIds, String processName,
            String[] threadNames, int[] cpuFrequencies, int[][] cpuTimes) {
        assertNotNull(processCpuUsage);
        assertEquals(processId, processCpuUsage.processId);
        assertEquals(uid, processCpuUsage.uid);
        assertEquals(processName, processCpuUsage.processName);
        assertEquals(threadIds.length, processCpuUsage.threadCpuUsages.size());

        // Sort the thread CPU usages to compare with test case
        final ArrayList<KernelCpuThreadReader.ThreadCpuUsage> threadCpuUsages =
                new ArrayList<>(processCpuUsage.threadCpuUsages);
        threadCpuUsages.sort(Comparator.comparingInt(a -> a.threadId));

        int threadCount = 0;
        for (KernelCpuThreadReader.ThreadCpuUsage threadCpuUsage : threadCpuUsages) {
            assertEquals(threadIds[threadCount], threadCpuUsage.threadId);
            assertEquals(threadNames[threadCount], threadCpuUsage.threadName);

            for (int i = 0; i < threadCpuUsage.usageTimesMillis.length; i++) {
                assertEquals(
                        cpuTimes[threadCount][i] * 10,
                        threadCpuUsage.usageTimesMillis[i]);
                assertEquals(
                        cpuFrequencies[i],
                        readerCpuFrequencies[i]);
            }
            threadCount++;
        }

        assertEquals(threadCount, threadIds.length);
    }

    @Test
    public void testBucketSetup_simple() {
        long[] frequencies = {1, 2, 3, 4, 1, 2, 3, 4};
        KernelCpuThreadReader.FrequencyBucketCreator
                frequencyBucketCreator = new KernelCpuThreadReader.FrequencyBucketCreator(
                frequencies, 4);
        assertArrayEquals(
                new int[]{1, 3, 1, 3},
                frequencyBucketCreator.getBucketMinFrequencies(frequencies));
        assertArrayEquals(
                new int[]{2, 2, 2, 2},
                frequencyBucketCreator.getBucketedValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
    }

    @Test
    public void testBucketSetup_noBig() {
        long[] frequencies = {1, 2, 3, 4, 5, 6, 7, 8};
        KernelCpuThreadReader.FrequencyBucketCreator
                frequencyBucketCreator = new KernelCpuThreadReader.FrequencyBucketCreator(
                frequencies, 4);
        assertArrayEquals(
                new int[]{1, 3, 5, 7},
                frequencyBucketCreator.getBucketMinFrequencies(frequencies));
        assertArrayEquals(
                new int[]{2, 2, 2, 2},
                frequencyBucketCreator.getBucketedValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
    }

    @Test
    public void testBucketSetup_moreLittle() {
        long[] frequencies = {1, 2, 3, 4, 5, 1, 2, 3};
        KernelCpuThreadReader.FrequencyBucketCreator
                frequencyBucketCreator = new KernelCpuThreadReader.FrequencyBucketCreator(
                frequencies, 4);
        assertArrayEquals(
                new int[]{1, 3, 1, 2},
                frequencyBucketCreator.getBucketMinFrequencies(frequencies));
        assertArrayEquals(
                new int[]{2, 3, 1, 2},
                frequencyBucketCreator.getBucketedValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
    }

    @Test
    public void testBucketSetup_moreBig() {
        long[] frequencies = {1, 2, 3, 1, 2, 3, 4, 5};
        KernelCpuThreadReader.FrequencyBucketCreator
                frequencyBucketCreator = new KernelCpuThreadReader.FrequencyBucketCreator(
                frequencies, 4);
        assertArrayEquals(
                new int[]{1, 2, 1, 3},
                frequencyBucketCreator.getBucketMinFrequencies(frequencies));
        assertArrayEquals(
                new int[]{1, 2, 2, 3},
                frequencyBucketCreator.getBucketedValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
    }

    @Test
    public void testBucketSetup_equalBuckets() {
        long[] frequencies = {1, 2, 3, 4, 1, 2, 3, 4};
        KernelCpuThreadReader.FrequencyBucketCreator
                frequencyBucketCreator = new KernelCpuThreadReader.FrequencyBucketCreator(
                frequencies, 8);
        assertArrayEquals(
                new int[]{1, 2, 3, 4, 1, 2, 3, 4},
                frequencyBucketCreator.getBucketMinFrequencies(frequencies));
        assertArrayEquals(
                new int[]{1, 1, 1, 1, 1, 1, 1, 1},
                frequencyBucketCreator.getBucketedValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
    }

    @Test
    public void testBucketSetup_moreBigBucketsThanFrequencies() {
        long[] frequencies = {1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3};
        KernelCpuThreadReader.FrequencyBucketCreator
                frequencyBucketCreator = new KernelCpuThreadReader.FrequencyBucketCreator(
                frequencies, 8);
        assertArrayEquals(
                new int[]{1, 3, 5, 7, 1, 2, 3},
                frequencyBucketCreator.getBucketMinFrequencies(frequencies));
        assertArrayEquals(
                new int[]{2, 2, 2, 3, 1, 1, 1},
                frequencyBucketCreator.getBucketedValues(
                        new long[]{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}));
    }

    @Test
    public void testBucketSetup_oneBucket() {
        long[] frequencies = {1, 2, 3, 4, 2, 3, 4, 5};
        KernelCpuThreadReader.FrequencyBucketCreator
                frequencyBucketCreator = new KernelCpuThreadReader.FrequencyBucketCreator(
                frequencies, 1);
        assertArrayEquals(
                new int[]{1},
                frequencyBucketCreator.getBucketMinFrequencies(frequencies));
        assertArrayEquals(
                new int[]{8},
                frequencyBucketCreator.getBucketedValues(
                        new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
    }

    @Test
    public void testGetBigFrequenciesStartIndex_simple() {
        assertEquals(
                3, KernelCpuThreadReader.FrequencyBucketCreator.getBigFrequenciesStartIndex(
                        new long[]{1, 2, 3, 1, 2, 3}));
    }

    @Test
    public void testGetBigFrequenciesStartIndex_moreLittle() {
        assertEquals(
                4, KernelCpuThreadReader.FrequencyBucketCreator.getBigFrequenciesStartIndex(
                        new long[]{1, 2, 3, 4, 1, 2}));
    }

    @Test
    public void testGetBigFrequenciesStartIndex_moreBig() {
        assertEquals(
                2, KernelCpuThreadReader.FrequencyBucketCreator.getBigFrequenciesStartIndex(
                        new long[]{1, 2, 1, 2, 3, 4}));
    }

    @Test
    public void testGetBigFrequenciesStartIndex_noBig() {
        assertEquals(
                4, KernelCpuThreadReader.FrequencyBucketCreator.getBigFrequenciesStartIndex(
                        new long[]{1, 2, 3, 4}));
    }

    @Test
    public void testUidPredicate_singleRange() {
        KernelCpuThreadReaderSettingsObserver.UidPredicate uidPredicate =
                KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString("1000-1999");
        assertTrue(uidPredicate.test(1000));
        assertTrue(uidPredicate.test(1050));
        assertTrue(uidPredicate.test(1999));
        assertFalse(uidPredicate.test(2000));
        assertFalse(uidPredicate.test(0));
        assertFalse(uidPredicate.test(10000));
        assertFalse(uidPredicate.test(-100));
    }

    @Test
    public void testUidPredicate_singleUid() {
        KernelCpuThreadReaderSettingsObserver.UidPredicate uidPredicate =
                KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString("1234-1234");
        assertTrue(uidPredicate.test(1234));
        assertFalse(uidPredicate.test(1235));
        assertFalse(uidPredicate.test(1232));
        assertFalse(uidPredicate.test(0));
        assertFalse(uidPredicate.test(-1234));
    }

    @Test
    public void testUidPredicate_uidAndRange() {
        KernelCpuThreadReaderSettingsObserver.UidPredicate uidPredicate =
                KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString(
                        "1000-1000;1050-1060");
        assertTrue(uidPredicate.test(1000));
        assertTrue(uidPredicate.test(1050));
        assertTrue(uidPredicate.test(1054));
        assertTrue(uidPredicate.test(1060));
        assertFalse(uidPredicate.test(1040));
        assertFalse(uidPredicate.test(1001));
        assertFalse(uidPredicate.test(0));
        assertFalse(uidPredicate.test(-1000));
    }

    @Test
    public void testUidPredicate_multiple() {
        KernelCpuThreadReaderSettingsObserver.UidPredicate uidPredicate =
                KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString(
                        "1000-1000;1050-1060;1001-1001;2000-3000");
        assertTrue(uidPredicate.test(1000));
        assertTrue(uidPredicate.test(1001));
        assertTrue(uidPredicate.test(1050));
        assertTrue(uidPredicate.test(1054));
        assertTrue(uidPredicate.test(1060));
        assertTrue(uidPredicate.test(1001));
        assertTrue(uidPredicate.test(2000));
        assertTrue(uidPredicate.test(2444));
        assertTrue(uidPredicate.test(3000));
        assertFalse(uidPredicate.test(0));
        assertFalse(uidPredicate.test(1040));
        assertFalse(uidPredicate.test(3001));
        assertFalse(uidPredicate.test(1999));
    }

    @Test
    public void testUidPredicate_zero() {
        KernelCpuThreadReaderSettingsObserver.UidPredicate uidPredicate =
                KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString("0-0");
        assertTrue(uidPredicate.test(0));
        assertFalse(uidPredicate.test(1));
        assertFalse(uidPredicate.test(2000));
        assertFalse(uidPredicate.test(10000));
        assertFalse(uidPredicate.test(-100));
    }

    @Test
    public void testUidPredicate_emptyRangeString() {
        assertThrows(
                NumberFormatException.class,
                () -> KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString(""));
    }

    @Test
    public void testUidPredicate_singleNumber() {
        assertThrows(
                NumberFormatException.class,
                () -> KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString("1000"));
    }

    @Test
    public void testUidPredicate_lettersInRange() {
        assertThrows(
                NumberFormatException.class,
                () -> KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString(
                        "0-0;1-1;a;3-3"));
    }

    @Test
    public void testUidPredicate_onlyLetters() {
        assertThrows(
                NumberFormatException.class,
                () -> KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString("abc"));
    }

    @Test
    public void testUidPredicate_backwardsRange() {
        assertThrows(
                IllegalArgumentException.class,
                () -> KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString("20-10"));
    }

    @Test
    public void testUidPredicate_comma() {
        assertThrows(
                NumberFormatException.class,
                () -> KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString("1-1,2-2,3-3"));
    }
}
