/*
 * Copyright (C) 2016 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.pm;

import android.os.Environment;
import android.os.SystemClock;
import android.util.AtomicFile;

import java.io.File;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;

/**
 * A simple base class for statistics that need to be saved/restored from a dedicated file. This
 * class provides a base implementation that:
 * <ul>
 * <li>Provide an AtomicFile to the actual read/write code
 * <li>A background-thread write and a synchronous write
 * <li>Write-limiting for the background-thread (by default writes are at least 30 minutes apart)
 * <li>Can lock on the provided data object before writing
 * </ul>
 * For completion, a subclass needs to implement actual {@link #writeInternal(Object) writing} and
 * {@link #readInternal(Object) reading}.
 */
public abstract class AbstractStatsBase<T> {

    private static final int WRITE_INTERVAL_MS =
            (PackageManagerService.DEBUG_DEXOPT) ? 0 : 30*60*1000;
    private final Object mFileLock = new Object();
    private final AtomicLong mLastTimeWritten = new AtomicLong(0);
    private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false);
    private final String mFileName;
    private final String mBackgroundThreadName;
    private final boolean mLock;

    protected AbstractStatsBase(String fileName, String threadName, boolean lock) {
        mFileName = fileName;
        mBackgroundThreadName = threadName;
        mLock = lock;
    }

    protected AtomicFile getFile() {
        File dataDir = Environment.getDataDirectory();
        File systemDir = new File(dataDir, "system");
        File fname = new File(systemDir, mFileName);
        return new AtomicFile(fname);
    }

    protected void writeNow(final T data) {
        writeImpl(data);
        mLastTimeWritten.set(SystemClock.elapsedRealtime());
    }

    protected boolean maybeWriteAsync(final T data) {
        if (SystemClock.elapsedRealtime() - mLastTimeWritten.get() < WRITE_INTERVAL_MS
            && !PackageManagerService.DEBUG_DEXOPT) {
            return false;
        }

        if (mBackgroundWriteRunning.compareAndSet(false, true)) {
            new Thread(mBackgroundThreadName) {
                @Override
                public void run() {
                    try {
                        writeImpl(data);
                        mLastTimeWritten.set(SystemClock.elapsedRealtime());
                    } finally {
                        mBackgroundWriteRunning.set(false);
                    }
                }
            }.start();
            return true;
        }

        return false;
    }

    private void writeImpl(T data) {
        if (mLock) {
            synchronized (data) {
                synchronized (mFileLock) {
                    writeInternal(data);
                }
            }
        } else {
            synchronized (mFileLock) {
                writeInternal(data);
            }
        }
    }

    protected abstract void writeInternal(T data);

    protected void read(T data) {
        if (mLock) {
            synchronized (data) {
                synchronized (mFileLock) {
                    readInternal(data);
                }
            }
        } else {
            synchronized (mFileLock) {
                readInternal(data);
            }
        }
        // We use the current time as last-written. read() is called on system server startup
        // (current situation), and we want to postpone I/O at boot.
        mLastTimeWritten.set(SystemClock.elapsedRealtime());
    }

    protected abstract void readInternal(T data);
}
