/*
 * Copyright (C) 2015 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.settings.applications;

import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.text.format.Formatter;
import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseArray;

import com.android.internal.app.ProcessMap;
import com.android.internal.app.procstats.DumpUtils;
import com.android.internal.app.procstats.IProcessStats;
import com.android.internal.app.procstats.ProcessState;
import com.android.internal.app.procstats.ProcessStats;
import com.android.internal.app.procstats.ProcessStats.ProcessDataCollection;
import com.android.internal.app.procstats.ProcessStats.TotalMemoryUseCollection;
import com.android.internal.app.procstats.ServiceState;
import com.android.internal.util.MemInfoReader;
import com.android.settings.R;
import com.android.settings.Utils;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class ProcStatsData {

    private static final String TAG = "ProcStatsManager";

    private static final boolean DEBUG = ProcessStatsUi.DEBUG;

    private static ProcessStats sStatsXfer;

    private PackageManager mPm;
    private Context mContext;
    private long memTotalTime;

    private IProcessStats mProcessStats;
    private ProcessStats mStats;

    private boolean mUseUss;
    private long mDuration;

    private int[] mMemStates;

    private int[] mStates;

    private MemInfo mMemInfo;

    private ArrayList<ProcStatsPackageEntry> pkgEntries;

    public ProcStatsData(Context context, boolean useXfer) {
        mContext = context;
        mPm = context.getPackageManager();
        mProcessStats = IProcessStats.Stub.asInterface(
                ServiceManager.getService(ProcessStats.SERVICE_NAME));
        mMemStates = ProcessStats.ALL_MEM_ADJ;
        mStates = ProcessStats.BACKGROUND_PROC_STATES;
        if (useXfer) {
            mStats = sStatsXfer;
        }
    }

    public void setTotalTime(int totalTime) {
        memTotalTime = totalTime;
    }

    public void xferStats() {
        sStatsXfer = mStats;
    }

    public void setMemStates(int[] memStates) {
        mMemStates = memStates;
        refreshStats(false);
    }

    public void setStats(int[] stats) {
        this.mStates = stats;
        refreshStats(false);
    }

    public int getMemState() {
        int factor = mStats.mMemFactor;
        if (factor == ProcessStats.ADJ_NOTHING) {
            return ProcessStats.ADJ_MEM_FACTOR_NORMAL;
        }
        if (factor >= ProcessStats.ADJ_SCREEN_ON) {
            factor -= ProcessStats.ADJ_SCREEN_ON;
        }
        return factor;
    }

    public MemInfo getMemInfo() {
        return mMemInfo;
    }

    public long getElapsedTime() {
        return mStats.mTimePeriodEndRealtime - mStats.mTimePeriodStartRealtime;
    }

    public void setDuration(long duration) {
        if (duration != mDuration) {
            mDuration = duration;
            refreshStats(true);
        }
    }

    public long getDuration() {
        return mDuration;
    }

    public List<ProcStatsPackageEntry> getEntries() {
        return pkgEntries;
    }

    public void refreshStats(boolean forceLoad) {
        if (mStats == null || forceLoad) {
            load();
        }

        pkgEntries = new ArrayList<>();

        long now = SystemClock.uptimeMillis();

        memTotalTime = DumpUtils.dumpSingleTime(null, null, mStats.mMemFactorDurations,
                mStats.mMemFactor, mStats.mStartTime, now);

        ProcessStats.TotalMemoryUseCollection totalMem = new ProcessStats.TotalMemoryUseCollection(
                ProcessStats.ALL_SCREEN_ADJ, mMemStates);
        mStats.computeTotalMemoryUse(totalMem, now);

        mMemInfo = new MemInfo(mContext, totalMem, memTotalTime);

        ProcessDataCollection bgTotals = new ProcessDataCollection(
                ProcessStats.ALL_SCREEN_ADJ, mMemStates, mStates);
        ProcessDataCollection runTotals = new ProcessDataCollection(
                ProcessStats.ALL_SCREEN_ADJ, mMemStates, ProcessStats.NON_CACHED_PROC_STATES);

        createPkgMap(getProcs(bgTotals, runTotals), bgTotals, runTotals);
        if (totalMem.sysMemZRamWeight > 0 && !totalMem.hasSwappedOutPss) {
            distributeZRam(totalMem.sysMemZRamWeight);
        }

        ProcStatsPackageEntry osPkg = createOsEntry(bgTotals, runTotals, totalMem,
                mMemInfo.baseCacheRam);
        pkgEntries.add(osPkg);
    }

    private void createPkgMap(ArrayList<ProcStatsEntry> procEntries, ProcessDataCollection bgTotals,
            ProcessDataCollection runTotals) {
        // Combine processes into packages.
        ArrayMap<String, ProcStatsPackageEntry> pkgMap = new ArrayMap<>();
        for (int i = procEntries.size() - 1; i >= 0; i--) {
            ProcStatsEntry proc = procEntries.get(i);
            proc.evaluateTargetPackage(mPm, mStats, bgTotals, runTotals, sEntryCompare, mUseUss);
            ProcStatsPackageEntry pkg = pkgMap.get(proc.mBestTargetPackage);
            if (pkg == null) {
                pkg = new ProcStatsPackageEntry(proc.mBestTargetPackage, memTotalTime);
                pkgMap.put(proc.mBestTargetPackage, pkg);
                pkgEntries.add(pkg);
            }
            pkg.addEntry(proc);
        }
    }

    private void distributeZRam(double zramWeight) {
        // Distribute kernel's Z-Ram across processes, based on how much they have been running.
        // The idea is that the memory used by the kernel for this is not really the kernel's
        // responsibility, but that of whoever got swapped in to it...  and we will take how
        // much a process runs for as a sign of the proportion of Z-Ram it is responsible for.

        long zramMem = (long) (zramWeight / memTotalTime);
        long totalTime = 0;
        for (int i = pkgEntries.size() - 1; i >= 0; i--) {
            ProcStatsPackageEntry entry = pkgEntries.get(i);
            for (int j = entry.mEntries.size() - 1; j >= 0; j--) {
                ProcStatsEntry proc = entry.mEntries.get(j);
                totalTime += proc.mRunDuration;
            }
        }
        for (int i = pkgEntries.size() - 1; i >= 0 && totalTime > 0; i--) {
            ProcStatsPackageEntry entry = pkgEntries.get(i);
            long pkgRunTime = 0;
            long maxRunTime = 0;
            for (int j = entry.mEntries.size() - 1; j >= 0; j--) {
                ProcStatsEntry proc = entry.mEntries.get(j);
                pkgRunTime += proc.mRunDuration;
                if (proc.mRunDuration > maxRunTime) {
                    maxRunTime = proc.mRunDuration;
                }
            }
            long pkgZRam = (zramMem*pkgRunTime)/totalTime;
            if (pkgZRam > 0) {
                zramMem -= pkgZRam;
                totalTime -= pkgRunTime;
                ProcStatsEntry procEntry = new ProcStatsEntry(entry.mPackage, 0,
                        mContext.getString(R.string.process_stats_os_zram), maxRunTime,
                        pkgZRam, memTotalTime);
                procEntry.evaluateTargetPackage(mPm, mStats, null, null, sEntryCompare, mUseUss);
                entry.addEntry(procEntry);
            }
        }
    }

    private ProcStatsPackageEntry createOsEntry(ProcessDataCollection bgTotals,
            ProcessDataCollection runTotals, TotalMemoryUseCollection totalMem, long baseCacheRam) {
        // Add in fake entry representing the OS itself.
        ProcStatsPackageEntry osPkg = new ProcStatsPackageEntry("os", memTotalTime);
        ProcStatsEntry osEntry;
        if (totalMem.sysMemNativeWeight > 0) {
            osEntry = new ProcStatsEntry(Utils.OS_PKG, 0,
                    mContext.getString(R.string.process_stats_os_native), memTotalTime,
                    (long) (totalMem.sysMemNativeWeight / memTotalTime), memTotalTime);
            osEntry.evaluateTargetPackage(mPm, mStats, bgTotals, runTotals, sEntryCompare, mUseUss);
            osPkg.addEntry(osEntry);
        }
        if (totalMem.sysMemKernelWeight > 0) {
            osEntry = new ProcStatsEntry(Utils.OS_PKG, 0,
                    mContext.getString(R.string.process_stats_os_kernel), memTotalTime,
                    (long) (totalMem.sysMemKernelWeight / memTotalTime), memTotalTime);
            osEntry.evaluateTargetPackage(mPm, mStats, bgTotals, runTotals, sEntryCompare, mUseUss);
            osPkg.addEntry(osEntry);
        }
        /*  Turned off now -- zram is being distributed across running apps.
        if (totalMem.sysMemZRamWeight > 0) {
            osEntry = new ProcStatsEntry(Utils.OS_PKG, 0,
                    mContext.getString(R.string.process_stats_os_zram), memTotalTime,
                    (long) (totalMem.sysMemZRamWeight / memTotalTime));
            osEntry.evaluateTargetPackage(mPm, mStats, bgTotals, runTotals, sEntryCompare, mUseUss);
            osPkg.addEntry(osEntry);
        }
        */
        if (baseCacheRam > 0) {
            osEntry = new ProcStatsEntry(Utils.OS_PKG, 0,
                    mContext.getString(R.string.process_stats_os_cache), memTotalTime,
                    baseCacheRam / 1024, memTotalTime);
            osEntry.evaluateTargetPackage(mPm, mStats, bgTotals, runTotals, sEntryCompare, mUseUss);
            osPkg.addEntry(osEntry);
        }
        return osPkg;
    }

    private ArrayList<ProcStatsEntry> getProcs(ProcessDataCollection bgTotals,
            ProcessDataCollection runTotals) {
        final ArrayList<ProcStatsEntry> procEntries = new ArrayList<>();
        if (DEBUG) Log.d(TAG, "-------------------- PULLING PROCESSES");

        final ProcessMap<ProcStatsEntry> entriesMap = new ProcessMap<ProcStatsEntry>();
        for (int ipkg = 0, N = mStats.mPackages.getMap().size(); ipkg < N; ipkg++) {
            final SparseArray<SparseArray<ProcessStats.PackageState>> pkgUids = mStats.mPackages
                    .getMap().valueAt(ipkg);
            for (int iu = 0; iu < pkgUids.size(); iu++) {
                final SparseArray<ProcessStats.PackageState> vpkgs = pkgUids.valueAt(iu);
                for (int iv = 0; iv < vpkgs.size(); iv++) {
                    final ProcessStats.PackageState st = vpkgs.valueAt(iv);
                    for (int iproc = 0; iproc < st.mProcesses.size(); iproc++) {
                        final ProcessState pkgProc = st.mProcesses.valueAt(iproc);
                        final ProcessState proc = mStats.mProcesses.get(pkgProc.getName(),
                                pkgProc.getUid());
                        if (proc == null) {
                            Log.w(TAG, "No process found for pkg " + st.mPackageName
                                    + "/" + st.mUid + " proc name " + pkgProc.getName());
                            continue;
                        }
                        ProcStatsEntry ent = entriesMap.get(proc.getName(), proc.getUid());
                        if (ent == null) {
                            ent = new ProcStatsEntry(proc, st.mPackageName, bgTotals, runTotals,
                                    mUseUss);
                            if (ent.mRunWeight > 0) {
                                if (DEBUG) Log.d(TAG, "Adding proc " + proc.getName() + "/"
                                            + proc.getUid() + ": time="
                                            + ProcessStatsUi.makeDuration(ent.mRunDuration) + " ("
                                            + ((((double) ent.mRunDuration) / memTotalTime) * 100)
                                            + "%)"
                                            + " pss=" + ent.mAvgRunMem);
                                entriesMap.put(proc.getName(), proc.getUid(), ent);
                                procEntries.add(ent);
                            }
                        } else {
                            ent.addPackage(st.mPackageName);
                        }
                    }
                }
            }
        }

        if (DEBUG) Log.d(TAG, "-------------------- MAPPING SERVICES");

        // Add in service info.
        for (int ip = 0, N = mStats.mPackages.getMap().size(); ip < N; ip++) {
            SparseArray<SparseArray<ProcessStats.PackageState>> uids = mStats.mPackages.getMap()
                    .valueAt(ip);
            for (int iu = 0; iu < uids.size(); iu++) {
                SparseArray<ProcessStats.PackageState> vpkgs = uids.valueAt(iu);
                for (int iv = 0; iv < vpkgs.size(); iv++) {
                    ProcessStats.PackageState ps = vpkgs.valueAt(iv);
                    for (int is = 0, NS = ps.mServices.size(); is < NS; is++) {
                        ServiceState ss = ps.mServices.valueAt(is);
                        if (ss.getProcessName() != null) {
                            ProcStatsEntry ent = entriesMap.get(ss.getProcessName(),
                                    uids.keyAt(iu));
                            if (ent != null) {
                                if (DEBUG) Log.d(TAG, "Adding service " + ps.mPackageName
                                            + "/" + ss.getName() + "/" + uids.keyAt(iu)
                                            + " to proc " + ss.getProcessName());
                                ent.addService(ss);
                            } else {
                                Log.w(TAG, "No process " + ss.getProcessName() + "/"
                                        + uids.keyAt(iu) + " for service " + ss.getName());
                            }
                        }
                    }
                }
            }
        }

        return procEntries;
    }

    private void load() {
        try {
            ParcelFileDescriptor pfd = mProcessStats.getStatsOverTime(mDuration);
            mStats = new ProcessStats(false);
            InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
            mStats.read(is);
            try {
                is.close();
            } catch (IOException e) {
            }
            if (mStats.mReadError != null) {
                Log.w(TAG, "Failure reading process stats: " + mStats.mReadError);
            }
        } catch (RemoteException e) {
            Log.e(TAG, "RemoteException:", e);
        }
    }

    public static class MemInfo {
        public double realUsedRam;
        public double realFreeRam;
        public double realTotalRam;
        long baseCacheRam;

        double[] mMemStateWeights = new double[ProcessStats.STATE_COUNT];
        double freeWeight;
        double usedWeight;
        double weightToRam;
        double totalRam;
        double totalScale;
        long memTotalTime;

        private MemInfo(Context context, ProcessStats.TotalMemoryUseCollection totalMem,
                long memTotalTime) {
            this.memTotalTime = memTotalTime;
            calculateWeightInfo(context, totalMem, memTotalTime);

            double usedRam = (usedWeight * 1024) / memTotalTime;
            double freeRam = (freeWeight * 1024) / memTotalTime;
            totalRam = usedRam + freeRam;
            totalScale = realTotalRam / totalRam;
            weightToRam = totalScale / memTotalTime * 1024;

            realUsedRam = usedRam * totalScale;
            realFreeRam = freeRam * totalScale;
            if (DEBUG) {
                Log.i(TAG, "Scaled Used RAM: " + Formatter.formatShortFileSize(context,
                        (long) realUsedRam));
                Log.i(TAG, "Scaled Free RAM: " + Formatter.formatShortFileSize(context,
                        (long) realFreeRam));
            }
            if (DEBUG) {
                Log.i(TAG, "Adj Scaled Used RAM: " + Formatter.formatShortFileSize(context,
                        (long) realUsedRam));
                Log.i(TAG, "Adj Scaled Free RAM: " + Formatter.formatShortFileSize(context,
                        (long) realFreeRam));
            }

            ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
            ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryInfo(
                    memInfo);
            if (memInfo.hiddenAppThreshold >= realFreeRam) {
                realUsedRam = freeRam;
                realFreeRam = 0;
                baseCacheRam = (long) realFreeRam;
            } else {
                realUsedRam += memInfo.hiddenAppThreshold;
                realFreeRam -= memInfo.hiddenAppThreshold;
                baseCacheRam = memInfo.hiddenAppThreshold;
            }
        }

        private void calculateWeightInfo(Context context, TotalMemoryUseCollection totalMem,
                long memTotalTime) {
            MemInfoReader memReader = new MemInfoReader();
            memReader.readMemInfo();
            realTotalRam = memReader.getTotalSize();
            freeWeight = totalMem.sysMemFreeWeight + totalMem.sysMemCachedWeight;
            usedWeight = totalMem.sysMemKernelWeight + totalMem.sysMemNativeWeight;
            if (!totalMem.hasSwappedOutPss) {
                usedWeight += totalMem.sysMemZRamWeight;
            }
            for (int i = 0; i < ProcessStats.STATE_COUNT; i++) {
                if (i == ProcessStats.STATE_SERVICE_RESTARTING) {
                    // These don't really run.
                    mMemStateWeights[i] = 0;
                } else {
                    mMemStateWeights[i] = totalMem.processStateWeight[i];
                    if (i >= ProcessStats.STATE_HOME) {
                        freeWeight += totalMem.processStateWeight[i];
                    } else {
                        usedWeight += totalMem.processStateWeight[i];
                    }
                }
            }
            if (DEBUG) {
                Log.i(TAG, "Used RAM: " + Formatter.formatShortFileSize(context,
                        (long) ((usedWeight * 1024) / memTotalTime)));
                Log.i(TAG, "Free RAM: " + Formatter.formatShortFileSize(context,
                        (long) ((freeWeight * 1024) / memTotalTime)));
                Log.i(TAG, "Total RAM: " + Formatter.formatShortFileSize(context,
                        (long) (((freeWeight + usedWeight) * 1024) / memTotalTime)));
            }
        }
    }

    final static Comparator<ProcStatsEntry> sEntryCompare = new Comparator<ProcStatsEntry>() {
        @Override
        public int compare(ProcStatsEntry lhs, ProcStatsEntry rhs) {
            if (lhs.mRunWeight < rhs.mRunWeight) {
                return 1;
            } else if (lhs.mRunWeight > rhs.mRunWeight) {
                return -1;
            } else if (lhs.mRunDuration < rhs.mRunDuration) {
                return 1;
            } else if (lhs.mRunDuration > rhs.mRunDuration) {
                return -1;
            }
            return 0;
        }
    };
}
