/*
 * 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.server.am;

import android.os.PowerManagerInternal;
import android.os.Process;
import android.os.SystemClock;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.ProcessCpuTracker;
import com.android.internal.util.RingBuffer;
import com.android.internal.util.function.pooled.PooledLambda;

import java.io.PrintWriter;

public class OomAdjProfiler {
    @GuardedBy("this")
    private boolean mOnBattery;
    @GuardedBy("this")
    private boolean mScreenOff;

    @GuardedBy("this")
    private long mOomAdjStartTimeMs;
    @GuardedBy("this")
    private boolean mOomAdjStarted;

    @GuardedBy("this")
    private CpuTimes mOomAdjRunTime = new CpuTimes();
    @GuardedBy("this")
    private CpuTimes mSystemServerCpuTime = new CpuTimes();

    @GuardedBy("this")
    private long mLastSystemServerCpuTimeMs;
    @GuardedBy("this")
    private boolean mSystemServerCpuTimeUpdateScheduled;
    private final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(false);

    @GuardedBy("this")
    final RingBuffer<CpuTimes> mOomAdjRunTimesHist = new RingBuffer<>(CpuTimes.class, 10);
    @GuardedBy("this")
    final RingBuffer<CpuTimes> mSystemServerCpuTimesHist = new RingBuffer<>(CpuTimes.class, 10);

    void batteryPowerChanged(boolean onBattery) {
        synchronized (this) {
            scheduleSystemServerCpuTimeUpdate();
            mOnBattery = onBattery;
        }
    }

    void onWakefulnessChanged(int wakefulness) {
        synchronized (this) {
            scheduleSystemServerCpuTimeUpdate();
            mScreenOff = wakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE;
        }
    }

    void oomAdjStarted() {
        synchronized (this) {
            mOomAdjStartTimeMs = SystemClock.currentThreadTimeMillis();
            mOomAdjStarted = true;
        }
    }

    void oomAdjEnded() {
        synchronized (this) {
            if (!mOomAdjStarted) {
                return;
            }
            mOomAdjRunTime.addCpuTimeMs(SystemClock.currentThreadTimeMillis() - mOomAdjStartTimeMs);
        }
    }

    private void scheduleSystemServerCpuTimeUpdate() {
        synchronized (this) {
            if (mSystemServerCpuTimeUpdateScheduled) {
                return;
            }
            mSystemServerCpuTimeUpdateScheduled = true;
            BackgroundThread.getHandler().sendMessage(PooledLambda.obtainMessage(
                    OomAdjProfiler::updateSystemServerCpuTime,
                    this, mOnBattery, mScreenOff));
        }
    }

    private void updateSystemServerCpuTime(boolean onBattery, boolean screenOff) {
        final long cpuTimeMs = mProcessCpuTracker.getCpuTimeForPid(Process.myPid());
        synchronized (this) {
            mSystemServerCpuTime.addCpuTimeMs(
                    cpuTimeMs - mLastSystemServerCpuTimeMs, onBattery, screenOff);
            mLastSystemServerCpuTimeMs = cpuTimeMs;
            mSystemServerCpuTimeUpdateScheduled = false;
            notifyAll();
        }
    }

    void reset() {
        synchronized (this) {
            if (mSystemServerCpuTime.isEmpty()) {
                return;
            }
            mOomAdjRunTimesHist.append(mOomAdjRunTime);
            mSystemServerCpuTimesHist.append(mSystemServerCpuTime);
            mOomAdjRunTime = new CpuTimes();
            mSystemServerCpuTime = new CpuTimes();
        }
    }

    void dump(PrintWriter pw) {
        synchronized (this) {
            if (mSystemServerCpuTimeUpdateScheduled) {
                while (mSystemServerCpuTimeUpdateScheduled) {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
            } else {
                updateSystemServerCpuTime(mOnBattery, mScreenOff);
            }

            pw.println("System server and oomAdj runtimes (ms) in recent battery sessions "
                    + "(most recent first):");
            if (!mSystemServerCpuTime.isEmpty()) {
                pw.print("  ");
                pw.print("system_server=");
                pw.print(mSystemServerCpuTime);
                pw.print("  ");
                pw.print("oom_adj=");
                pw.println(mOomAdjRunTime);
            }
            final CpuTimes[] systemServerCpuTimes = mSystemServerCpuTimesHist.toArray();
            final CpuTimes[] oomAdjRunTimes = mOomAdjRunTimesHist.toArray();
            for (int i = oomAdjRunTimes.length - 1; i >= 0; --i) {
                pw.print("  ");
                pw.print("system_server=");
                pw.print(systemServerCpuTimes[i]);
                pw.print("  ");
                pw.print("oom_adj=");
                pw.println(oomAdjRunTimes[i]);
            }
        }
    }

    private class CpuTimes {
        private long mOnBatteryTimeMs;
        private long mOnBatteryScreenOffTimeMs;

        public void addCpuTimeMs(long cpuTimeMs) {
            addCpuTimeMs(cpuTimeMs, mOnBattery, mScreenOff);
        }

        public void addCpuTimeMs(long cpuTimeMs, boolean onBattery, boolean screenOff) {
            if (onBattery) {
                mOnBatteryTimeMs += cpuTimeMs;
                if (screenOff) {
                    mOnBatteryScreenOffTimeMs += cpuTimeMs;
                }
            }
        }

        public boolean isEmpty() {
            return mOnBatteryTimeMs == 0 && mOnBatteryScreenOffTimeMs == 0;
        }

        public String toString() {
            return "[" + mOnBatteryTimeMs + "," + mOnBatteryScreenOffTimeMs + "]";
        }
    }
}
