/*
 * Copyright (C) 2021 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.cts.verifier.audio;

import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.TextView;

import com.android.compatibility.common.util.CddTest;
import com.android.compatibility.common.util.ResultType;
import com.android.compatibility.common.util.ResultUnit;
import com.android.cts.verifier.CtsVerifierReportLog;
import com.android.cts.verifier.PassFailButtons;
import com.android.cts.verifier.R;
import com.android.cts.verifier.audio.audiolib.AudioSystemFlags;
import com.android.cts.verifier.audio.audiolib.CircularBufferFloat;
import com.android.cts.verifier.audio.audiolib.StatUtils;
import com.android.cts.verifier.audio.audiolib.TapLatencyAnalyser;
import com.android.cts.verifier.audio.audiolib.WaveformView;
import com.android.cts.verifier.audio.sources.BlipAudioSourceProvider;

import org.hyphonate.megaaudio.common.BuilderBase;
import org.hyphonate.megaaudio.duplex.DuplexAudioManager;
import org.hyphonate.megaaudio.player.AudioSource;
import org.hyphonate.megaaudio.player.AudioSourceProvider;
import org.hyphonate.megaaudio.player.JavaSourceProxy;
import org.hyphonate.megaaudio.recorder.AudioSinkProvider;
import org.hyphonate.megaaudio.recorder.sinks.AppCallback;
import org.hyphonate.megaaudio.recorder.sinks.AppCallbackAudioSinkProvider;

/**
 * CtsVerifier test to measure tap-to-tone latency.
 */
@CddTest(requirement = "5.6")
public class AudioTap2ToneActivity
        extends PassFailButtons.Activity
        implements View.OnClickListener, AppCallback {
    private static final String TAG = "AudioTap2ToneActivity";

    // JNI load
    static {
        try {
            System.loadLibrary("megaaudio_jni");
        } catch (UnsatisfiedLinkError e) {
            Log.e(TAG, "Error loading MegaAudio JNI library");
            Log.e(TAG, "e: " + e);
            e.printStackTrace();
        }

        /* TODO: gracefully fail/notify if the library can't be loaded */
    }

    private boolean mIsRecording;

    private int mPlayerType = BuilderBase.TYPE_OBOE | BuilderBase.SUB_TYPE_OBOE_AAUDIO;

    private DuplexAudioManager mDuplexAudioManager;
    private AudioSource mBlipSource;

    private Button mStartBtn;
    private Button mStopBtn;

    private TextView mSpecView;
    private TextView mResultsView;
    private TextView mStatsView;
    private TextView mPhaseView;

    private WaveformView mWaveformView;

    // Test Constants are from OboeTester.AudioMidiTester
    private static final float MAX_TOUCH_LATENCY = 0.200f;
    private static final float MAX_OUTPUT_LATENCY = 0.600f;
    private static final float ANALYSIS_TIME_MARGIN = 0.250f;

    private static final float ANALYSIS_TIME_DELAY = MAX_OUTPUT_LATENCY;
    private static final float ANALYSIS_TIME_TOTAL = MAX_TOUCH_LATENCY + MAX_OUTPUT_LATENCY;
    private static final float ANALYSIS_TIME_MAX = ANALYSIS_TIME_TOTAL + ANALYSIS_TIME_MARGIN;
    private static final int ANALYSIS_SAMPLE_RATE = 48000; // need not match output rate

    private static final int NUM_RECORD_CHANNELS = 1;

    private CircularBufferFloat mInputBuffer;

    private Runnable mAnalysisTask;
    private int mTaskCountdown;

    private TapLatencyAnalyser mTapLatencyAnalyser;

    // Stats for latency
    private double mMaxRequiredLatency;

    // REQUIRED CDD  5.6/H-1-1
    private static final int MAX_TAP_2_TONE_LATENCY_BASIC = 500;  // ms
    // Requirement for "R" and "S"
    private static final int MAX_TAP_2_TONE_LATENCY_RS = 100;  // ms
    // Requirement for "T"
    private static final int MAX_TAP_2_TONE_LATENCY_T     = 80;   // ms
    // Requirement for any builds declaring "ProAudio" and "LowLatency"
    private static final int MAX_TAP_2_TONE_LATENCY_PRO     = 80;   // ms
    private static final int MAX_TAP_2_TONE_LATENCY_LOW     = 80;   // ms

    // Test API (back-end) IDs
    private static final int NUM_TEST_APIS = 2;
    private static final int TEST_API_NATIVE = 0;
    private static final int TEST_API_JAVA = 1;
    private int mActiveTestAPI = TEST_API_NATIVE;

    private int[] mNumMeasurements = new int[NUM_TEST_APIS];
    private int[] mLatencySumSamples = new int[NUM_TEST_APIS];
    private double[] mLatencyMin = new double[NUM_TEST_APIS];   // ms
    private double[] mLatencyMax = new double[NUM_TEST_APIS];   // ms
    private double[] mLatencyAve = new double[NUM_TEST_APIS];   // ms

    // Test State
    private static final int NUM_TEST_PHASES = 5;
    private int mTestPhase;
    private boolean mArmed = true;  // OK to fire another beep

    private double[] mLatencyMillis = new double[NUM_TEST_PHASES];

    // ReportLog Schema
    // Note that each key will be suffixed with the ID of the API tested
    private static final String KEY_LATENCY_MIN = "latency_min_";
    private static final String KEY_LATENCY_MAX = "latency_max_";
    private static final String KEY_LATENCY_AVE = "latency_max_";
    private static final String KEY_LATENCY_NUM_MEASUREMENTS = "latency_num_measurements_";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setContentView(R.layout.audio_tap2tone_activity);

        super.onCreate(savedInstanceState);

        // Setup UI
        String yesString = getResources().getString(R.string.audio_general_yes);
        String noString = getResources().getString(R.string.audio_general_no);

        boolean claimsProAudio = AudioSystemFlags.claimsProAudio(this);
        boolean claimsLowLatencyAudio = AudioSystemFlags.claimsLowLatencyAudio(this);

        ((TextView) findViewById(R.id.audio_t2t_pro_audio))
                .setText(claimsProAudio ? yesString : noString);
        ((TextView) findViewById(R.id.audio_t2t_low_latency))
                .setText(claimsLowLatencyAudio ? yesString : noString);

        String mediaPerformanceClassString;
        if (Build.VERSION.MEDIA_PERFORMANCE_CLASS == Build.VERSION_CODES.TIRAMISU) {
            mediaPerformanceClassString = "T";
        } else if (Build.VERSION.MEDIA_PERFORMANCE_CLASS == Build.VERSION_CODES.S)  {
            mediaPerformanceClassString = "S";
        } else if (Build.VERSION.MEDIA_PERFORMANCE_CLASS == Build.VERSION_CODES.R) {
            mediaPerformanceClassString = "R";
        } else {
            mediaPerformanceClassString = "none";
        }
        ((TextView) findViewById(R.id.audio_t2t_mpc)).setText(mediaPerformanceClassString);

        // Note: These tests need to be ordered such that we find the LOWEST allowable latency
        mMaxRequiredLatency = MAX_TAP_2_TONE_LATENCY_BASIC;
        if (claimsProAudio) {
            mMaxRequiredLatency = Math.min(mMaxRequiredLatency, MAX_TAP_2_TONE_LATENCY_PRO);
        }
        if (claimsLowLatencyAudio) {
            mMaxRequiredLatency = Math.min(mMaxRequiredLatency, MAX_TAP_2_TONE_LATENCY_LOW);
        }
        if (Build.VERSION.MEDIA_PERFORMANCE_CLASS == Build.VERSION_CODES.TIRAMISU) {
            mMaxRequiredLatency = Math.min(mMaxRequiredLatency, MAX_TAP_2_TONE_LATENCY_T);
        }
        if (Build.VERSION.MEDIA_PERFORMANCE_CLASS == Build.VERSION_CODES.R
                || Build.VERSION.MEDIA_PERFORMANCE_CLASS == Build.VERSION_CODES.S) {
            mMaxRequiredLatency = Math.min(mMaxRequiredLatency, MAX_TAP_2_TONE_LATENCY_RS);
        }

        ((TextView) findViewById(R.id.audio_t2t_required_latency))
                .setText("" + mMaxRequiredLatency + "ms");

        mStartBtn = (Button) findViewById(R.id.tap2tone_startBtn);
        mStartBtn.setOnClickListener(this);
        mStopBtn = (Button) findViewById(R.id.tap2tone_stopBtn);
        mStopBtn.setOnClickListener(this);

        ((RadioButton) findViewById(R.id.audioJavaApiBtn)).setOnClickListener(this);
        RadioButton nativeApiRB = findViewById(R.id.audioNativeApiBtn);
        nativeApiRB.setChecked(true);
        nativeApiRB.setOnClickListener(this);

        ((Button) findViewById(R.id.tap2tone_clearResults)).setOnClickListener(this);

        mSpecView = (TextView) findViewById(R.id.tap2tone_specTxt);
        mResultsView = (TextView) findViewById(R.id.tap2tone_resultTxt);
        mStatsView = (TextView) findViewById(R.id.tap2tone_statsTxt);
        mPhaseView = (TextView) findViewById(R.id.tap2tone_phaseInfo);

        mWaveformView = (WaveformView) findViewById(R.id.tap2tone_waveView);
        // Start a blip test when the waveform view is tapped.
        mWaveformView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent event) {
                int action = event.getActionMasked();
                switch (action) {
                    case MotionEvent.ACTION_DOWN:
                    case MotionEvent.ACTION_POINTER_DOWN:
                        trigger();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        break;
                    case MotionEvent.ACTION_UP:
                    case MotionEvent.ACTION_POINTER_UP:
                        break;
                }
                // Must return true or we do not get the ACTION_MOVE and
                // ACTION_UP events.
                return true;
            }
        });

        setPassFailButtonClickListeners();
        setInfoResources(R.string.audio_tap2tone, R.string.audio_tap2tone_info, -1);

        enableAudioButtons();

        // Setup analysis
        int numBufferSamples = (int) (ANALYSIS_TIME_MAX * ANALYSIS_SAMPLE_RATE);
        mInputBuffer = new CircularBufferFloat(numBufferSamples);
        mTapLatencyAnalyser = new TapLatencyAnalyser();

        JavaSourceProxy.initN();

        calculateTestPass();
    }

    private void startAudio() {
        if (mIsRecording) {
            return;
        }

        if (mDuplexAudioManager == null) {
            AudioSourceProvider sourceProvider = new BlipAudioSourceProvider();
            AudioSinkProvider sinkProvider = new AppCallbackAudioSinkProvider(this);
            mDuplexAudioManager = new DuplexAudioManager(sourceProvider, sinkProvider);
            mDuplexAudioManager.setNumRecorderChannels(NUM_RECORD_CHANNELS);
        }

        mDuplexAudioManager.setupStreams(mPlayerType, BuilderBase.TYPE_JAVA);
        mDuplexAudioManager.start();

        mBlipSource = (AudioSource) mDuplexAudioManager.getAudioSource();

        mIsRecording = true;
        enableAudioButtons();
    }

    private void stopAudio() {
        if (mIsRecording) {
            mDuplexAudioManager.stop();
            // is there a teardown method here?
            mIsRecording = false;
            enableAudioButtons();
        }
    }

    private void resetStats() {
        mNumMeasurements[mActiveTestAPI] = 0;
        mLatencySumSamples[mActiveTestAPI] = 0;
        mLatencyMin[mActiveTestAPI] =
            mLatencyMax[mActiveTestAPI] =
            mLatencyAve[mActiveTestAPI] = 0;

        java.util.Arrays.fill(mLatencyMillis, 0.0);

        mTestPhase = 0;
    }

    private void clearResults() {
        resetStats();
        mSpecView.setText("");
        mResultsView.setText("");
        mStatsView.setText("");
    }

    private void enableAudioButtons() {
        mStartBtn.setEnabled(!mIsRecording);
        mStopBtn.setEnabled(mIsRecording);
    }

    private void calculateTestPass() {
        boolean testCompleted = mTestPhase >= NUM_TEST_PHASES;
        if (!testCompleted) {
            mSpecView.setText(getResources().getString(R.string.audio_general_testnotcompleted));
            getPassButton().setEnabled(false);
            return;
        }

        double averageLatency = mLatencyAve[mActiveTestAPI];
        boolean pass = averageLatency != 0 && averageLatency <= mMaxRequiredLatency;

        if (pass) {
            mSpecView.setText("Average: " + averageLatency + " ms <= "
                    + mMaxRequiredLatency + " ms -- PASS");
        } else {
            mSpecView.setText("Average: " + averageLatency + " ms > "
                    + mMaxRequiredLatency + " ms -- FAIL");
        }
        getPassButton().setEnabled(pass);
    }

    private void recordTestStatus() {
        CtsVerifierReportLog reportLog = getReportLog();
        for (int api = TEST_API_NATIVE; api <= TEST_API_JAVA; api++) {
            reportLog.addValue(
                    KEY_LATENCY_MIN + api,
                    mLatencyMin[api],
                    ResultType.NEUTRAL,
                    ResultUnit.NONE);
            reportLog.addValue(
                    KEY_LATENCY_MAX + api,
                    mLatencyMax[api],
                    ResultType.NEUTRAL,
                    ResultUnit.NONE);
            reportLog.addValue(
                    KEY_LATENCY_AVE + api,
                    mLatencyAve[api],
                    ResultType.NEUTRAL,
                    ResultUnit.NONE);
            reportLog.addValue(
                    KEY_LATENCY_NUM_MEASUREMENTS + api,
                    mNumMeasurements[api],
                    ResultType.NEUTRAL,
                    ResultUnit.NONE);
        }

        reportLog.submit();
    }

    private void trigger() {
        if (mIsRecording) {
            if (mArmed) {
                mArmed = false;

                mBlipSource.trigger();

                // schedule an analysis to start in the near future
                mAnalysisTask = new Runnable() {
                    public void run() {
                        new Thread() {
                            public void run() {
                                analyzeCapturedAudio();
                            }
                        }.start();
                    }
                };
                mTaskCountdown = (int) (mDuplexAudioManager.getRecorder().getSampleRate()
                                            * ANALYSIS_TIME_DELAY);

            }
        }
    }

    /**
     * A holder for analysis results/
     */
    public static class TestResult {
        public float[] samples;
        public float[] filtered;
        public int frameRate;
        public TapLatencyAnalyser.TapLatencyEvent[] events;
    }

    private void processTest(TestResult result) {
        if (mTestPhase == NUM_TEST_PHASES) {
            mTestPhase--;
        }

        int[] cursors = new int[2];
        cursors[0] = result.events[0].sampleIndex;
        cursors[1] = result.events[1].sampleIndex;
        mWaveformView.setCursorData(cursors);

        int latencySamples = cursors[1] - cursors[0];
        mLatencySumSamples[mActiveTestAPI] += latencySamples;
        mNumMeasurements[mActiveTestAPI]++;

        double latencyMillis = 1000 * latencySamples / result.frameRate;
        mLatencyMillis[mTestPhase] = latencyMillis;

        if (mLatencyMin[mActiveTestAPI] == 0
                || mLatencyMin[mActiveTestAPI] > latencyMillis) {
            mLatencyMin[mActiveTestAPI] = latencyMillis;
        }
        if (mLatencyMax[mActiveTestAPI] == 0
                || mLatencyMax[mActiveTestAPI] < latencyMillis) {
            mLatencyMax[mActiveTestAPI] = latencyMillis;
        }

        mLatencyAve[mActiveTestAPI] = StatUtils.calculateMean(mLatencyMillis);
        double meanAbsoluteDeviation = StatUtils.calculateMeanAbsoluteDeviation(
                mLatencyAve[mActiveTestAPI], mLatencyMillis, mTestPhase + 1);

        mTestPhase++;

        mLatencyAve[mActiveTestAPI] = 1000
                * (mLatencySumSamples[mActiveTestAPI] / mNumMeasurements[mActiveTestAPI])
                / result.frameRate;
        mResultsView.setText("Phase: " + mTestPhase + " : " + latencyMillis
                + " ms, Ave: " + mLatencyAve[mActiveTestAPI] + " ms");
        mStatsView.setText("Deviation: " + String.format("%.2f",meanAbsoluteDeviation));

        mPhaseView.setText("" + mTestPhase + " of " + NUM_TEST_PHASES + " completed.");
    }

    private void analyzeCapturedAudio() {
        if (!mIsRecording) {
            return;
        }
        int sampleRate = mDuplexAudioManager.getRecorder().getSampleRate();
        int numSamples = (int) (sampleRate * ANALYSIS_TIME_TOTAL);
        float[] buffer = new float[numSamples];

        int numRead = mInputBuffer.readMostRecent(buffer);

        TestResult result = new TestResult();
        result.samples = buffer;
        result.frameRate = sampleRate;
        result.events = mTapLatencyAnalyser.analyze(buffer, 0, numRead);
        result.filtered = mTapLatencyAnalyser.getFilteredBuffer();

        // This will come in on a background thread, so switch to the UI thread to update the UI.
        runOnUiThread(new Runnable() {
            public void run() {
                if (result.events.length < 2) {
                    mResultsView.setText(
                            getResources().getString(R.string.audio_tap2tone_too_few));
                    mStatsView.setText("");
                } else if (result.events.length > 2) {
                    mResultsView.setText(
                            getResources().getString(R.string.audio_tap2tone_too_many));
                    mStatsView.setText("");
                } else {
                    processTest(result);
                }

                mWaveformView.setSampleData(result.filtered);
                mWaveformView.postInvalidate();

                mArmed = true;

                calculateTestPass();
            }
        });
    }

    //
    // View.OnClickListener overrides
    //
    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.tap2tone_startBtn) {
            startAudio();
        } else if (id == R.id.tap2tone_stopBtn) {
            stopAudio();
        } else if (id == R.id.audioJavaApiBtn) {
            stopAudio();
            clearResults();
            mPlayerType = BuilderBase.TYPE_JAVA;
            mActiveTestAPI = TEST_API_JAVA;
        } else if (id == R.id.audioNativeApiBtn) {
            stopAudio();
            clearResults();
            mPlayerType = BuilderBase.TYPE_OBOE | BuilderBase.SUB_TYPE_OBOE_AAUDIO;
            mActiveTestAPI = TEST_API_NATIVE;
        } else if (id == R.id.tap2tone_clearResults) {
                clearResults();
        }
    }

    @Override
    public void setTestResultAndFinish(boolean passed) {
        stopAudio();
        recordTestStatus();
        super.setTestResultAndFinish(passed);
    }

    //
    // AppCallback overrides
    //
    @Override
    public void onDataReady(float[] audioData, int numFrames) {
        mInputBuffer.write(audioData);

        // Analysis?
        if (mTaskCountdown > 0) {
            mTaskCountdown -= numFrames;
            if (mTaskCountdown <= 0) {
                mTaskCountdown = 0;
                new Thread(mAnalysisTask).start(); // run asynchronously with audio thread
            }
        }
    }
}
