/*
 * 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.nn.benchmark.app;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Trace;
import android.util.Log;
import android.util.Pair;
import android.view.WindowManager;
import android.widget.TextView;

import com.android.nn.benchmark.core.BenchmarkException;
import com.android.nn.benchmark.core.BenchmarkResult;
import com.android.nn.benchmark.core.InferenceInOutSequence;
import com.android.nn.benchmark.core.InferenceResult;
import com.android.nn.benchmark.core.NNTestBase;
import com.android.nn.benchmark.core.TestModels;
import com.android.nn.benchmark.core.UnsupportedSdkException;

import java.util.List;
import java.io.IOException;

public class NNBenchmark extends Activity {
    protected static final String TAG = "NN_BENCHMARK";

    public static final String EXTRA_ENABLE_LONG = "enable long";
    public static final String EXTRA_ENABLE_PAUSE = "enable pause";
    public static final String EXTRA_DISABLE_NNAPI = "disable NNAPI";
    public static final String EXTRA_DEMO = "demo";
    public static final String EXTRA_TESTS = "tests";

    public static final String EXTRA_RESULTS_TESTS = "tests";
    public static final String EXTRA_RESULTS_RESULTS = "results";

    private int mTestList[];
    private BenchmarkResult mTestResults[];

    private TextView mTextView;
    private boolean mToggleLong;
    private boolean mTogglePause;

    private boolean mUseNNApi;
    private boolean mCompleteInputSet;

    protected void setUseNNApi(boolean useNNApi) {
        mUseNNApi = useNNApi;
    }

    protected void setCompleteInputSet(boolean completeInputSet) {
        mCompleteInputSet = completeInputSet;
    }

    // Initialize the parameters for Instrumentation tests.
    protected void prepareInstrumentationTest() {
        mTestList = new int[1];
        mTestResults = new BenchmarkResult[1];
        mProcessor = new Processor();
    }

    /////////////////////////////////////////////////////////////////////////
    // Processor is a helper thread for running the work without
    // blocking the UI thread.
    class Processor extends Thread {
        private float mLastResult;
        private boolean mRun = true;
        private boolean mDoingBenchmark;
        private NNTestBase mTest;

        // Method to retrieve benchmark results for instrumentation tests.
        BenchmarkResult getInstrumentationResult(
                TestModels.TestModelEntry t, float warmupTimeSeconds, float runTimeSeconds)
                throws IOException {
            mTest = changeTest(mTest, t);
            return getBenchmark(warmupTimeSeconds, runTimeSeconds);
        }

        // Run one loop of kernels for at least the specified minimum time.
        // The function returns the average time in ms for the test run
        private BenchmarkResult runBenchmarkLoop(float minTime, boolean completeInputSet)
                throws IOException {
            try {
                // Run the kernel
                Pair<List<InferenceInOutSequence>, List<InferenceResult>> results;
                if (minTime > 0.f) {
                    if (completeInputSet) {
                        results = mTest.runBenchmarkCompleteInputSet(1, minTime);
                    } else {
                        results = mTest.runBenchmark(minTime);
                    }
                } else {
                    results = mTest.runInferenceOnce();
                }
                return BenchmarkResult.fromInferenceResults(
                        mTest.getTestInfo(),
                        mUseNNApi ? BenchmarkResult.BACKEND_TFLITE_NNAPI
                                : BenchmarkResult.BACKEND_TFLITE_CPU,
                        results.first, results.second, mTest.getEvaluator());
            } catch (BenchmarkException e) {
                return new BenchmarkResult(e.getMessage());
            }
        }


        // Get a benchmark result for a specific test
        private BenchmarkResult getBenchmark(float warmupTimeSeconds, float runTimeSeconds)
            throws IOException {
            try {
                mTest.checkSdkVersion();
            } catch (UnsupportedSdkException e) {
                BenchmarkResult r = new BenchmarkResult(e.getMessage());
                Log.v(TAG, "Test: " + r.toString());
                return r;
            }

            mDoingBenchmark = true;

            long result = 0;

            // We run a short bit of work before starting the actual test
            // this is to let any power management do its job and respond.
            // For NNAPI systrace usage documentation, see
            // frameworks/ml/nn/common/include/Tracing.h.
            try {
                final String traceName = "[NN_LA_PWU]runBenchmarkLoop";
                Trace.beginSection(traceName);
                runBenchmarkLoop(warmupTimeSeconds, false);
            } finally {
                Trace.endSection();
            }

            // Run the actual benchmark
            BenchmarkResult r;
            try {
                final String traceName = "[NN_LA_PBM]runBenchmarkLoop";
                Trace.beginSection(traceName);
                r = runBenchmarkLoop(runTimeSeconds, mCompleteInputSet);
            } finally {
                Trace.endSection();
            }

            Log.v(TAG, "Test: " + r.toString());

            mDoingBenchmark = false;
            return r;
        }

        @Override
        public void run() {
            while (mRun) {
                // Our loop for launching tests or benchmarks
                synchronized (this) {
                    // We may have been asked to exit while waiting
                    if (!mRun) return;
                }

                try {
                    // Loop over the tests we want to benchmark
                    for (int ct = 0; (ct < mTestList.length) && mRun; ct++) {

                        // For reproducibility we wait a short time for any sporadic work
                        // created by the user touching the screen to launch the test to pass.
                        // Also allows for things to settle after the test changes.
                        try {
                            sleep(250);
                        } catch (InterruptedException e) {
                        }

                        TestModels.TestModelEntry testModel =
                            TestModels.modelsList().get(mTestList[ct]);
                        int testNumber = ct + 1;
                        runOnUiThread(() -> {
                            mTextView.setText(
                                String.format(
                                    "Running test %d of %d: %s",
                                    testNumber,
                                    mTestList.length,
                                    testModel.toString()));
                        });

                        // Select the next test
                        mTest = changeTest(mTest, testModel);

                        // If the user selected the "long pause" option, wait
                        if (mTogglePause) {
                            for (int i = 0; (i < 100) && mRun; i++) {
                                try {
                                    sleep(100);
                                } catch (InterruptedException e) {
                                }
                            }
                        }

                        // Run the test
                        float warmupTime = 0.3f;
                        float runTime = 1.f;
                        if (mToggleLong) {
                            warmupTime = 2.f;
                            runTime = 10.f;
                        }
                        mTestResults[ct] = getBenchmark(warmupTime, runTime);
                    }
                    onBenchmarkFinish(mRun);
                } catch (IOException e) {
                    Log.e(TAG, "Exception during benchmark run", e);
                    break;
                }
            }
        }

        public void exit() {
            mRun = false;

            synchronized (this) {
                notifyAll();
            }

            try {
                this.join();
            } catch (InterruptedException e) {
            }

            if (mTest != null) {
                mTest.destroy();
                mTest = null;
            }
        }
    }


    private boolean mDoingBenchmark;
    public Processor mProcessor;

    NNTestBase changeTest(NNTestBase oldTestBase, TestModels.TestModelEntry t) {
        if (oldTestBase != null) {
            // Make sure we don't leak memory.
            oldTestBase.destroy();
        }
        NNTestBase tb = t.createNNTestBase(mUseNNApi,
                false /* enableIntermediateTensorsDump */);
        tb.setupModel(this);
        return tb;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mTextView = new TextView(this);
        mTextView.setTextSize(20);
        mTextView.setText("Running NN benchmark...");
        setContentView(mTextView);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mProcessor != null) {
            mProcessor.exit();
        }
    }

    public void onBenchmarkFinish(boolean ok) {
        if (ok) {
            Intent intent = new Intent();
            intent.putExtra(EXTRA_RESULTS_TESTS, mTestList);
            intent.putExtra(EXTRA_RESULTS_RESULTS, mTestResults);
            setResult(RESULT_OK, intent);
        } else {
            setResult(RESULT_CANCELED);
        }
        finish();
    }

    @Override
    protected void onResume() {
        super.onResume();
        Intent i = getIntent();
        mTestList = i.getIntArrayExtra(EXTRA_TESTS);
        mToggleLong = i.getBooleanExtra(EXTRA_ENABLE_LONG, false);
        mTogglePause = i.getBooleanExtra(EXTRA_ENABLE_PAUSE, false);
        setUseNNApi(!i.getBooleanExtra(EXTRA_DISABLE_NNAPI, false));

        if (mTestList != null) {
            mTestResults = new BenchmarkResult[mTestList.length];
            mProcessor = new Processor();
            mProcessor.start();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }
}
