/*
 * Copyright (C) 2020 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 static com.android.cts.verifier.TestListActivity.sCurrentDisplayMode;
import static com.android.cts.verifier.TestListAdapter.setTestNameSuffix;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.graphics.Color;
import android.media.AudioDeviceCallback;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
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.PassFailButtons;
import com.android.cts.verifier.R;

import org.hyphonate.megaaudio.player.AudioSourceProvider;
import org.hyphonate.megaaudio.player.JavaPlayer;
import org.hyphonate.megaaudio.player.PlayerBuilder;
import org.hyphonate.megaaudio.player.sources.SinAudioSourceProvider;

@CddTest(requirement = "7.8.2.1/C-1-1,C-1-2,C-1-3,C-1-4,C-2-1")
public class AnalogHeadsetAudioActivity
        extends PassFailButtons.Activity
        implements View.OnClickListener {
    private static final String TAG = AnalogHeadsetAudioActivity.class.getSimpleName();
    private static final boolean DEBUG = false;

    private AudioManager    mAudioManager;

    // UI
    private TextView mHasPortQueryText;
    private Button mHasAnalogPortYesBtn;
    private Button mHasAnalogPortNoBtn;

    private Button mPlayButton;
    private Button mStopButton;
    private Button mPlaybackSuccessBtn;
    private Button mPlaybackFailBtn;
    private TextView mPlaybackStatusTxt;

    private TextView mHeadsetNameText;
    private TextView mHeadsetPlugMessage;

    private TextView mButtonsPromptTxt;
    private TextView mHeadsetHookText;
    private TextView mHeadsetVolUpText;
    private TextView mHeadsetVolDownText;

    // Devices
    private AudioDeviceInfo mHeadsetDeviceInfo;
    private boolean mHasHeadsetPort;
    private boolean mPlugIntentReceived;
    private boolean mPlaybackSuccess;

    // Intents
    private HeadsetPlugReceiver mHeadsetPlugReceiver;

    // Buttons
    private boolean mHasHeadsetHook;
    private boolean mHasPlayPause;
    private boolean mHasVolUp;
    private boolean mHasVolDown;

    private TextView mResultsTxt;

    // Player
    protected boolean mIsPlaying = false;

    // Mega Player
    static final int NUM_CHANNELS = 2;
    static final int SAMPLE_RATE = 48000;

    JavaPlayer mAudioPlayer;

    // ReportLog Schema
    private static final String SECTION_ANALOG_HEADSET = "analog_headset_activity";
    private static final String KEY_HAS_HEADSET_PORT = "has_headset_port";
    private static final String KEY_HEADSET_PLUG_INTENT_STATE = "intent_received_state";
    private static final String KEY_CLAIMS_HEADSET_PORT = "claims_headset_port";
    private static final String KEY_HEADSET_CONNECTED = "headset_connected";
    private static final String KEY_KEYCODE_HEADSETHOOK = "keycode_headset_hook";
    private static final String KEY_KEYCODE_PLAY_PAUSE = "keycode_play_pause";
    private static final String KEY_KEYCODE_VOLUME_UP = "keycode_volume_up";
    private static final String KEY_KEYCODE_VOLUME_DOWN = "keycode_volume_down";

    public AnalogHeadsetAudioActivity() {
        super();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.audio_headset_audio_activity);

        mHeadsetNameText = (TextView)findViewById(R.id.headset_analog_name);
        mHeadsetPlugMessage = (TextView)findViewById(R.id.headset_analog_plug_message);

        // Analog Port?
        mHasPortQueryText = (TextView)findViewById(R.id.analog_headset_query) ;
        mHasAnalogPortYesBtn = (Button)findViewById(R.id.headset_analog_port_yes);
        mHasAnalogPortYesBtn.setOnClickListener(this);
        mHasAnalogPortNoBtn = (Button)findViewById(R.id.headset_analog_port_no);
        mHasAnalogPortNoBtn.setOnClickListener(this);

        // Player Controls.
        mPlayButton = (Button)findViewById(R.id.headset_analog_play);
        mPlayButton.setOnClickListener(this);
        mStopButton = (Button)findViewById(R.id.headset_analog_stop);
        mStopButton.setOnClickListener(this);
        mPlaybackStatusTxt = (TextView)findViewById(R.id.analog_headset_playback_status);

        // Play Status
        mPlaybackSuccessBtn = (Button)findViewById(R.id.headset_analog_play_yes);
        mPlaybackSuccessBtn.setOnClickListener(this);
        mPlaybackFailBtn = (Button)findViewById(R.id.headset_analog_play_no);
        mPlaybackFailBtn.setOnClickListener(this);
        mPlaybackSuccessBtn.setEnabled(false);
        mPlaybackFailBtn.setEnabled(false);

        // Keycodes
        mButtonsPromptTxt = (TextView)findViewById(R.id.analog_headset_keycodes_prompt);
        mHeadsetHookText = (TextView)findViewById(R.id.headset_keycode_headsethook);
        mHeadsetVolUpText = (TextView)findViewById(R.id.headset_keycode_volume_up);
        mHeadsetVolDownText = (TextView)findViewById(R.id.headset_keycode_volume_down);

        mResultsTxt = (TextView)findViewById(R.id.headset_results);

        mAudioManager = (AudioManager)getSystemService(AUDIO_SERVICE);

        setupPlayer();

        mAudioManager.registerAudioDeviceCallback(new ConnectListener(), new Handler());

        mHeadsetPlugReceiver = new HeadsetPlugReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_HEADSET_PLUG);
        registerReceiver(mHeadsetPlugReceiver, filter);

        showKeyMessagesState();

        setInfoResources(R.string.analog_headset_test, R.string.analog_headset_test_info, -1);

        setPassFailButtonClickListeners();
        getPassButton().setEnabled(false);
    }

    //
    // Reporting
    //
    private boolean calculatePass() {
        if (!mHasHeadsetPort) {
            mResultsTxt.setText(getResources().getString(R.string.analog_headset_pass_noheadset));
            return true;
        } else {
            boolean pass = isReportLogOkToPass()
                    && mPlugIntentReceived
                    && mHeadsetDeviceInfo != null
                    && mPlaybackSuccess
                    && (mHasHeadsetHook || mHasPlayPause) && mHasVolUp && mHasVolDown;
            if (pass) {
                mResultsTxt.setText(getResources().getString(R.string.analog_headset_pass));
            } else if (!isReportLogOkToPass()) {
                mResultsTxt.setText(getResources().getString(R.string.audio_general_reportlogtest));
            }
            return pass;
        }
    }

    //
    // PassFailButtons Overrides
    //
    @Override
    public String getReportFileName() { return PassFailButtons.AUDIO_TESTS_REPORT_LOG_NAME; }

    @Override
    public final String getReportSectionName() {
        return setTestNameSuffix(sCurrentDisplayMode, SECTION_ANALOG_HEADSET);
    }

    @Override
    public void recordTestResults() {
        getReportLog().submit();
    }

    private void reportHeadsetPort(boolean has) {
        mHasHeadsetPort = has;
        getReportLog().addValue(
                KEY_HAS_HEADSET_PORT,
                has ? 1 : 0,
                ResultType.NEUTRAL,
                ResultUnit.NONE);
        enablePlayerButtons(has && mHeadsetDeviceInfo != null);

        if (!has) {
            // no port, so can't test. Let them pass
            getPassButton().setEnabled(calculatePass());
        }
    }

    private void reportPlugIntent(Intent intent) {
        // NOTE: This is a "sticky" intent meaning that if a headset has EVER been plugged in
        // (since a reboot), we will receive this intent.
        Resources resources = getResources();

        // [C-1-4] MUST trigger ACTION_HEADSET_PLUG upon a plug insert,
        // but only after all contacts on plug are touching their relevant segments on the jack.
        mPlugIntentReceived = true;

        // state - 0 for unplugged, 1 for plugged.
        // name - Headset type, human readable string
        // microphone - 1 if headset has a microphone, 0 otherwise

        int state = intent.getIntExtra("state", -1);
        if (state != -1) {
            StringBuilder sb = new StringBuilder();
            sb.append(resources.getString(R.string.analog_headset_action_received)
                    + resources.getString(
                            state == 0 ? R.string.analog_headset_unplugged
                                       : R.string.analog_headset_plugged));

            String name = intent.getStringExtra("name");
            if (name != null) {
                sb.append(" - " + name);
            }

            int hasMic = intent.getIntExtra("microphone", 0);
            if (hasMic == 1) {
                sb.append(resources.getString(R.string.analog_headset_mic));
            }

            mHeadsetPlugMessage.setText(sb.toString());

            // If we receive this intent, there is no need to ask if there is an analog jack.
            reportHeadsetPort(true);

            mHasPortQueryText.setText(getResources().getString(
                    R.string.analog_headset_port_detected));
            mHasAnalogPortYesBtn.setVisibility(View.GONE);
            mHasAnalogPortNoBtn.setVisibility(View.GONE);

            mPlaybackStatusTxt.setText(getResources().getString(
                    R.string.analog_headset_playback_prompt));
        }

        getReportLog().addValue(
                KEY_HEADSET_PLUG_INTENT_STATE,
                state,
                ResultType.NEUTRAL,
                ResultUnit.NONE);
    }

    private void reportPlaybackStatus(boolean success) {
        // [C-1-1] MUST support audio playback to stereo headphones
        // and stereo headsets with a microphone.
        mPlaybackSuccess = success;

        mPlaybackSuccessBtn.setEnabled(success);
        mPlaybackFailBtn.setEnabled(!success);

        getPassButton().setEnabled(calculatePass());

        getReportLog().addValue(
                KEY_CLAIMS_HEADSET_PORT,
                success ? 1 : 0,
                ResultType.NEUTRAL,
                ResultUnit.NONE);

        if (success) {
            mButtonsPromptTxt.setText(getResources().getString(
                    R.string.analog_headset_press_buttons));
        }
    }

    //
    // UI
    //
    private void showConnectedDevice() {
        if (mHeadsetDeviceInfo != null) {
            mHeadsetNameText.setText(getResources().getString(
                    R.string.analog_headset_headset_connected));
        } else {
            mHeadsetNameText.setText(getResources().getString(R.string.analog_headset_no_headset));
        }
    }

    private void enablePlayerButtons(boolean enabled) {
        mPlayButton.setEnabled(enabled);
        mStopButton.setEnabled(enabled);
    }

    private void showKeyMessagesState() {
        mHeadsetHookText.setTextColor((mHasHeadsetHook || mHasPlayPause)
                ? Color.WHITE : Color.GRAY);
        mHeadsetVolUpText.setTextColor(mHasVolUp ? Color.WHITE : Color.GRAY);
        mHeadsetVolDownText.setTextColor(mHasVolDown ? Color.WHITE : Color.GRAY);
    }

    //
    // Player
    //
    protected void setupPlayer() {
        //
        // Allocate the source provider for the sort of signal we want to play
        //
        AudioSourceProvider sourceProvider = new SinAudioSourceProvider();
        try {
            PlayerBuilder builder = new PlayerBuilder();
            mAudioPlayer = (JavaPlayer)builder
                    // choose one or the other of these for a Java or an Oboe player
                    .setPlayerType(PlayerBuilder.TYPE_JAVA)
                    // .setPlayerType(PlayerBuilder.PLAYER_OBOE)
                    .setSourceProvider(sourceProvider)
                    .build();
        } catch (PlayerBuilder.BadStateException ex) {
            Log.e(TAG, "Failed MegaPlayer build.");
        }
    }

    protected void startPlay() {
        if (!mIsPlaying) {
            //TODO - explain the choice of 96 here.
            mAudioPlayer.setupStream(NUM_CHANNELS, SAMPLE_RATE, 96);
            mAudioPlayer.startStream();
            mIsPlaying = true;

            mPlayButton.setEnabled(false);
            mStopButton.setEnabled(true);
        }
    }

    protected void stopPlay() {
        if (mIsPlaying) {
            mAudioPlayer.stopStream();
            mAudioPlayer.teardownStream();
            mIsPlaying = false;

            mPlayButton.setEnabled(true);
            mStopButton.setEnabled(false);

            mPlaybackStatusTxt.setText(getResources().getString(
                    R.string.analog_headset_playback_query));
        }
    }

    //
    // View.OnClickHandler
    //
    @Override
    public void onClick(View view) {
        int id = view.getId();
        if (id == R.id.headset_analog_port_yes) {
            reportHeadsetPort(true);
        } else if (id == R.id.headset_analog_port_no) {
            reportHeadsetPort(false);
        } else if (id == R.id.headset_analog_play) {
            startPlay();
        } else if (id == R.id.headset_analog_stop) {
            stopPlay();
            mPlaybackSuccessBtn.setEnabled(true);
            mPlaybackFailBtn.setEnabled(true);
        } else if (id == R.id.headset_analog_play_yes) {
            reportPlaybackStatus(true);
        } else if (id == R.id.headset_analog_play_no) {
            reportPlaybackStatus(false);
        }
    }

    //
    // Devices
    //
    private void scanPeripheralList(AudioDeviceInfo[] devices) {
        mHeadsetDeviceInfo = null;
        for(AudioDeviceInfo devInfo : devices) {
            if (devInfo.getType() == AudioDeviceInfo.TYPE_WIRED_HEADSET ||
                    devInfo.getType() == AudioDeviceInfo.TYPE_WIRED_HEADPHONES) {
                mHeadsetDeviceInfo = devInfo;
                break;
            }
        }

        getReportLog().addValue(
                KEY_HEADSET_CONNECTED,
                mHeadsetDeviceInfo != null ? 1 : 0,
                ResultType.NEUTRAL,
                ResultUnit.NONE);

        reportHeadsetPort(mHeadsetDeviceInfo != null);

        showConnectedDevice();
    }

    private class ConnectListener extends AudioDeviceCallback {
        /*package*/ ConnectListener() {}

        //
        // AudioDevicesManager.OnDeviceConnectionListener
        //
        @Override
        public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
            Log.i(TAG, "onAudioDevicesAdded() num:" + addedDevices.length);

            scanPeripheralList(mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL));
        }

        @Override
        public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
            Log.i(TAG, "onAudioDevicesRemoved() num:" + removedDevices.length);

            scanPeripheralList(mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL));
        }
    }

    private class HeadsetPlugReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            reportPlugIntent(intent);
        }
    }

    //
    // Keycodes
    //
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        // Log.i(TAG, "onKeyDown(" + keyCode + ")");
        switch (keyCode) {
            case KeyEvent.KEYCODE_HEADSETHOOK:
                mHasHeadsetHook = true;
                showKeyMessagesState();
                getPassButton().setEnabled(calculatePass());
                getReportLog().addValue(
                        KEY_KEYCODE_HEADSETHOOK, 1, ResultType.NEUTRAL, ResultUnit.NONE);
                break;

            case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
                mHasPlayPause = true;
                showKeyMessagesState();
                getPassButton().setEnabled(calculatePass());
                getReportLog().addValue(
                        KEY_KEYCODE_PLAY_PAUSE, 1, ResultType.NEUTRAL, ResultUnit.NONE);
                break;

            case KeyEvent.KEYCODE_VOLUME_UP:
                mHasVolUp = true;
                showKeyMessagesState();
                getPassButton().setEnabled(calculatePass());
                getReportLog().addValue(
                        KEY_KEYCODE_VOLUME_UP, 1, ResultType.NEUTRAL, ResultUnit.NONE);
                break;

            case KeyEvent.KEYCODE_VOLUME_DOWN:
                mHasVolDown = true;
                showKeyMessagesState();
                getPassButton().setEnabled(calculatePass());
                getReportLog().addValue(
                        KEY_KEYCODE_VOLUME_DOWN, 1, ResultType.NEUTRAL, ResultUnit.NONE);
                break;
        }
        return super.onKeyDown(keyCode, event);
    }
}
