/*
 * 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 android.multiuser;

import android.annotation.Nullable;
import android.os.Bundle;
import android.os.SystemClock;
import android.perftests.utils.ShellHelper;

import java.util.ArrayList;

// Based on //platform/frameworks/base/apct-tests/perftests/utils/BenchmarkState.java
public class BenchmarkRunner {

    private static final long COOL_OFF_PERIOD_MS = 1000;

    private static final int NUM_ITERATIONS = 4;

    private static final int NOT_STARTED = 0;  // The benchmark has not started yet.
    private static final int RUNNING = 1;  // The benchmark is running.
    private static final int PAUSED = 2; // The benchmark is paused
    private static final int FINISHED = 3;  // The benchmark has stopped.

    private final BenchmarkResults mResults = new BenchmarkResults();
    private int mState = NOT_STARTED;  // Current benchmark state.
    private int mIteration = 1;

    public long mStartTimeNs;
    public long mPausedDurationNs;
    public long mPausedTimeNs;

    private Throwable mFirstFailure = null;

    public boolean keepRunning() {
        switch (mState) {
            case NOT_STARTED:
                mState = RUNNING;
                prepareForNextRun();
                return true;
            case RUNNING:
                mIteration++;
                return startNextTestRun();
            case PAUSED:
                throw new IllegalStateException("Benchmarking is in paused state");
            case FINISHED:
                throw new IllegalStateException("Benchmarking is finished");
            default:
                throw new IllegalStateException("BenchmarkRunner is in unknown state");
        }
    }

    private boolean startNextTestRun() {
        mResults.addDuration(System.nanoTime() - mStartTimeNs - mPausedDurationNs);
        if (mIteration == NUM_ITERATIONS + 1) {
            mState = FINISHED;
            return false;
        } else {
            prepareForNextRun();
            return true;
        }
    }

    private void prepareForNextRun() {
        SystemClock.sleep(COOL_OFF_PERIOD_MS);
        ShellHelper.runShellCommand("am wait-for-broadcast-idle");
        mStartTimeNs = System.nanoTime();
        mPausedDurationNs = 0;
    }

    public void pauseTiming() {
        if (mState != RUNNING) {
            throw new IllegalStateException("Unable to pause the runner: not running currently");
        }
        mPausedTimeNs = System.nanoTime();
        mState = PAUSED;
    }

    public void resumeTiming() {
        if (mState != PAUSED) {
            throw new IllegalStateException("Unable to resume the runner: already running");
        }
        mPausedDurationNs += System.nanoTime() - mPausedTimeNs;
        mState = RUNNING;
    }

    public Bundle getStatsToReport() {
        return mResults.getStatsToReport();
    }

    public Bundle getStatsToLog() {
        return mResults.getStatsToLog();
    }

    public ArrayList<Long> getAllDurations() {
        return mResults.getAllDurations();
    }

    /** Returns which iteration (starting at 1) the Runner is currently on. */
    public int getIteration() {
        return mIteration;
    }

    /**
     * Marks the test run as failed, along with a message of why.
     * Only the first fail message is retained.
     */
    public void markAsFailed(Throwable err) {
        if (mFirstFailure == null) {
            mFirstFailure = err;
        }
    }

    /** Gets the failure message if the test failed; otherwise {@code null}. */
    public @Nullable Throwable getErrorOrNull() {
        if (mFirstFailure != null) {
            return mFirstFailure;
        }
        if (mState != FINISHED) {
            return new AssertionError("BenchmarkRunner state is not FINISHED.");
        }
        return null;
    }
}