/*
 * Copyright (C) 2017 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 android.os.BatteryStats.STATS_SINCE_CHARGED;
import static android.os.BatteryStats.Uid.NUM_PROCESS_STATE;
import static android.os.BatteryStats.Uid.PROCESS_STATE_BACKGROUND;
import static android.os.BatteryStats.Uid.PROCESS_STATE_CACHED;
import static android.os.BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE;
import static android.os.BatteryStats.Uid.PROCESS_STATE_TOP;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;

import android.os.BatteryStats;
import android.support.test.filters.LargeTest;
import android.support.test.runner.AndroidJUnit4;
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.Display;

import com.android.internal.util.ArrayUtils;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.Arrays;

@LargeTest
@RunWith(AndroidJUnit4.class)
public class BatteryStatsImplTest {
    @Mock
    private KernelUidCpuFreqTimeReader mKernelUidCpuFreqTimeReader;
    @Mock
    private KernelSingleUidTimeReader mKernelSingleUidTimeReader;

    private MockBatteryStatsImpl mBatteryStatsImpl;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);

        when(mKernelUidCpuFreqTimeReader.allUidTimesAvailable()).thenReturn(true);
        when(mKernelSingleUidTimeReader.singleUidCpuTimesAvailable()).thenReturn(true);
        mBatteryStatsImpl = new MockBatteryStatsImpl()
                .setKernelUidCpuFreqTimeReader(mKernelUidCpuFreqTimeReader)
                .setKernelSingleUidTimeReader(mKernelSingleUidTimeReader);
    }

    @Test
    public void testUpdateProcStateCpuTimes() {
        mBatteryStatsImpl.setOnBatteryInternal(true);
        mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_ON, 0, 0);

        final int[] testUids = {10032, 10048, 10145, 10139};
        final int[] testProcStates = {
                PROCESS_STATE_BACKGROUND,
                PROCESS_STATE_FOREGROUND_SERVICE,
                PROCESS_STATE_TOP,
                PROCESS_STATE_CACHED
        };
        addPendingUids(testUids, testProcStates);
        final long[][] cpuTimes = {
                {349734983, 394982394832l, 909834, 348934, 9838},
                {7498, 1239890, 988, 13298, 98980},
                {989834, 384098, 98483, 23809, 4984},
                {4859048, 348903, 4578967, 5973894, 298549}
        };
        for (int i = 0; i < testUids.length; ++i) {
            when(mKernelSingleUidTimeReader.readDeltaMs(testUids[i])).thenReturn(cpuTimes[i]);

            // Verify there are no cpu times initially.
            final BatteryStats.Uid u = mBatteryStatsImpl.getUidStatsLocked(testUids[i]);
            for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) {
                assertNull(u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                assertNull(u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED, procState));
            }
        }

        mBatteryStatsImpl.updateProcStateCpuTimes();

        verifyNoPendingUids();
        for (int i = 0; i < testUids.length; ++i) {
            final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]);
            for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) {
                if (procState == testProcStates[i]) {
                    assertArrayEquals("Uid=" + testUids[i], cpuTimes[i],
                            u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                } else {
                    assertNull(u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                }
                assertNull(u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED, procState));
            }
        }

        final long[][] delta1 = {
                {9589, 148934, 309894, 3098493, 98754},
                {21983, 94983, 4983, 9878493, 84854},
                {945894, 9089432, 19478, 3834, 7845},
                {843895, 43948, 949582, 99, 384}
        };
        for (int i = 0; i < testUids.length; ++i) {
            when(mKernelSingleUidTimeReader.readDeltaMs(testUids[i])).thenReturn(delta1[i]);
        }
        addPendingUids(testUids, testProcStates);

        mBatteryStatsImpl.updateProcStateCpuTimes();

        verifyNoPendingUids();
        for (int i = 0; i < testUids.length; ++i) {
            final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]);
            for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) {
                if (procState == testProcStates[i]) {
                    long[] expectedCpuTimes = cpuTimes[i].clone();
                    for (int j = 0; j < expectedCpuTimes.length; ++j) {
                        expectedCpuTimes[j] += delta1[i][j];
                    }
                    assertArrayEquals("Uid=" + testUids[i], expectedCpuTimes,
                            u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                } else {
                    assertNull(u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                }
                assertNull(u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED, procState));
            }
        }

        mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
        final long[][] delta2 = {
                {95932, 2943, 49834, 89034, 139},
                {349, 89605, 5896, 845, 98444},
                {678, 7498, 9843, 889, 4894},
                {488, 998, 8498, 394, 574}
        };
        for (int i = 0; i < testUids.length; ++i) {
            when(mKernelSingleUidTimeReader.readDeltaMs(testUids[i])).thenReturn(delta2[i]);
        }
        addPendingUids(testUids, testProcStates);

        mBatteryStatsImpl.updateProcStateCpuTimes();

        verifyNoPendingUids();
        for (int i = 0; i < testUids.length; ++i) {
            final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]);
            for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) {
                if (procState == testProcStates[i]) {
                    long[] expectedCpuTimes = cpuTimes[i].clone();
                    for (int j = 0; j < expectedCpuTimes.length; ++j) {
                        expectedCpuTimes[j] += delta1[i][j] + delta2[i][j];
                    }
                    assertArrayEquals("Uid=" + testUids[i], expectedCpuTimes,
                            u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                    assertArrayEquals("Uid=" + testUids[i], delta2[i],
                            u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                } else {
                    assertNull(u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                    assertNull(u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                }
            }
        }

        final long[][] delta3 = {
                {98545, 95768795, 76586, 548945, 57846},
                {788876, 586, 578459, 8776984, 9578923},
                {3049509483598l, 4597834, 377654, 94589035, 7854},
                {9493, 784, 99895, 8974893, 9879843}
        };
        for (int i = 0; i < testUids.length; ++i) {
            when(mKernelSingleUidTimeReader.readDeltaMs(testUids[i])).thenReturn(
                    delta3[i].clone());
        }
        addPendingUids(testUids, testProcStates);
        final int parentUid = testUids[1];
        final int childUid = 99099;
        addIsolatedUid(parentUid, childUid);
        final long[] isolatedUidCpuTimes = {495784, 398473, 4895, 4905, 30984093};
        when(mKernelSingleUidTimeReader.readDeltaMs(childUid)).thenReturn(isolatedUidCpuTimes);

        mBatteryStatsImpl.updateProcStateCpuTimes();

        verifyNoPendingUids();
        for (int i = 0; i < testUids.length; ++i) {
            final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]);
            for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) {
                if (procState == testProcStates[i]) {
                    long[] expectedCpuTimes = cpuTimes[i].clone();
                    for (int j = 0; j < expectedCpuTimes.length; ++j) {
                        expectedCpuTimes[j] += delta1[i][j] + delta2[i][j] + delta3[i][j]
                                + (testUids[i] == parentUid ? isolatedUidCpuTimes[j] : 0);
                    }
                    assertArrayEquals("Uid=" + testUids[i], expectedCpuTimes,
                            u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                    long[] expectedScreenOffTimes = delta2[i].clone();
                    for (int j = 0; j < expectedScreenOffTimes.length; ++j) {
                        expectedScreenOffTimes[j] += delta3[i][j]
                                + (testUids[i] == parentUid ? isolatedUidCpuTimes[j] : 0);
                    }
                    assertArrayEquals("Uid=" + testUids[i], expectedScreenOffTimes,
                            u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                } else {
                    assertNull(u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                    assertNull(u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                }
            }
        }
    }

    @Test
    public void testCopyFromAllUidsCpuTimes() {
        mBatteryStatsImpl.setOnBatteryInternal(true);
        mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_ON, 0, 0);

        final int[] testUids = {10032, 10048, 10145, 10139};
        final int[] testProcStates = {
                PROCESS_STATE_BACKGROUND,
                PROCESS_STATE_FOREGROUND_SERVICE,
                PROCESS_STATE_TOP,
                PROCESS_STATE_CACHED
        };
        final int[] pendingUidIdx = {1, 2};
        updateProcessStates(testUids, testProcStates, pendingUidIdx);

        final SparseArray<long[]> allUidCpuTimes = new SparseArray<>();
        long[][] allCpuTimes = {
                {938483, 4985984, 439893},
                {499, 94904, 27694},
                {302949085, 39789473, 34792839},
                {9809485, 9083475, 347889834},
        };
        for (int i = 0; i < testUids.length; ++i) {
            allUidCpuTimes.put(testUids[i], allCpuTimes[i]);
        }
        when(mKernelUidCpuFreqTimeReader.getAllUidCpuFreqTimeMs()).thenReturn(allUidCpuTimes);
        long[][] expectedCpuTimes = {
                {843598745, 397843, 32749, 99854},
                {9834, 5885, 487589, 394},
                {203984, 439, 9859, 30948},
                {9389, 858, 239, 349}
        };
        for (int i = 0; i < testUids.length; ++i) {
            final int idx = i;
            final ArgumentMatcher<long[]> matcher = times -> Arrays.equals(times, allCpuTimes[idx]);
            when(mKernelSingleUidTimeReader.computeDelta(eq(testUids[i]), argThat(matcher)))
                    .thenReturn(expectedCpuTimes[i]);
        }

        mBatteryStatsImpl.copyFromAllUidsCpuTimes();

        verifyNoPendingUids();
        for (int i = 0; i < testUids.length; ++i) {
            final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]);
            for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) {
                if (procState == testProcStates[i]) {
                    assertArrayEquals("Uid=" + testUids[i], expectedCpuTimes[i],
                            u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                } else {
                    assertNull(u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                }
                assertNull(u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED, procState));
            }
        }
    }

    @Test
    public void testAddCpuTimes() {
        long[] timesA = null;
        long[] timesB = null;
        assertNull(mBatteryStatsImpl.addCpuTimes(timesA, timesB));

        timesA = new long[] {34, 23, 45, 24};
        assertArrayEquals(timesA, mBatteryStatsImpl.addCpuTimes(timesA, timesB));

        timesB = timesA;
        timesA = null;
        assertArrayEquals(timesB, mBatteryStatsImpl.addCpuTimes(timesA, timesB));

        final long[] expected = {434, 6784, 34987, 9984};
        timesA = new long[timesB.length];
        for (int i = 0; i < timesA.length; ++i) {
            timesA[i] = expected[i] - timesB[i];
        }
        assertArrayEquals(expected, mBatteryStatsImpl.addCpuTimes(timesA, timesB));
    }

    private void addIsolatedUid(int parentUid, int childUid) {
        final BatteryStatsImpl.Uid u = mBatteryStatsImpl.getUidStatsLocked(parentUid);
        u.addIsolatedUid(childUid);
    }

    private void addPendingUids(int[] uids, int[] procStates) {
        final SparseIntArray pendingUids = mBatteryStatsImpl.getPendingUids();
        for (int i = 0; i < uids.length; ++i) {
            pendingUids.put(uids[i], procStates[i]);
        }
    }

    private void updateProcessStates(int[] uids, int[] procStates,
            int[] pendingUidsIdx) {
        final SparseIntArray pendingUids = mBatteryStatsImpl.getPendingUids();
        for (int i = 0; i < uids.length; ++i) {
            final BatteryStatsImpl.Uid u = mBatteryStatsImpl.getUidStatsLocked(uids[i]);
            if (ArrayUtils.contains(pendingUidsIdx, i)) {
                u.setProcessStateForTest(PROCESS_STATE_TOP);
                pendingUids.put(uids[i], procStates[i]);
            } else {
                u.setProcessStateForTest(procStates[i]);
            }
        }
    }

    private void verifyNoPendingUids() {
        final SparseIntArray pendingUids = mBatteryStatsImpl.getPendingUids();
        assertEquals("There shouldn't be any pending uids left: " + pendingUids,
                0, pendingUids.size());
    }
}
