/*
 * Copyright (C) 2018 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 java.io.IOException;

import android.media.midi.MidiDevice;
import android.media.midi.MidiDeviceInfo;
import android.media.midi.MidiManager;
import android.media.midi.MidiReceiver;
import android.os.Bundle;
import android.util.Log;

import com.android.compatibility.common.util.CddTest;

import com.android.cts.verifier.audio.midilib.MidiIODevice;
import com.android.cts.verifier.audio.midilib.NativeMidiManager;
import com.android.cts.verifier.R;

/*
 * A note about the USB MIDI device.
 * Any USB MIDI peripheral with standard female DIN jacks can be used. A standard MIDI cable
 * plugged into both input and output is required for the USB Loopback Test. A Bluetooth MIDI
 * device like the Yamaha MD-BT01 plugged into both input and output is required for the
 * Bluetooth Loopback test.
 */

/*
 * A note about the "virtual MIDI" device...
 * See file MidiEchoService for implementation of the echo server itself.
 * This service is started by the main manifest file (AndroidManifest.xml).
 */

/*
 * A note about Bluetooth MIDI devices...
 * Any Bluetooth MIDI device needs to be paired with the DUT with the "MIDI+BTLE" application
 * available in the Play Store:
 * (https://play.google.com/store/apps/details?id=com.mobileer.example.midibtlepairing).
 */

/**
 * CTS Verifier Activity for MIDI test
 */
@CddTest(requirement = "5.9/C-1-3,C-1-2")
public class MidiNativeTestActivity extends MidiTestActivityBase {
    private static final String TAG = "MidiNativeTestActivity";
    private static final boolean DEBUG = false;

    public MidiNativeTestActivity() {
        super();
        initTestModules(new NativeMidiTestModule(MidiDeviceInfo.TYPE_USB),
                new NativeMidiTestModule(MidiDeviceInfo.TYPE_VIRTUAL),
                new BTMidiTestModule());

        NativeMidiManager.loadNativeAPI();
        NativeMidiManager.initN();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        if (DEBUG) {
            Log.i(TAG, "---- onCreate()");
        }

        setContentView(R.layout.ndk_midi_activity);

        super.onCreate(savedInstanceState);

        startMidiEchoServer();
        scanMidiDevices();

        connectDeviceListener();
    }

    @Override
    protected void onPause () {
        super.onPause();
        if (DEBUG) {
            Log.i(TAG, "---- onPause()");
        }

        boolean isFound = stopService(mMidiServiceIntent);
        if (DEBUG) {
            Log.i(TAG, "---- Stop Service: " + isFound);
        }
    }

    /**
     * A class to control and represent the state of a given test.
     * It hold the data needed for IO, and the logic for sending, receiving and matching
     * the MIDI data stream.
     */
    public class NativeMidiTestModule extends MidiTestModule {
        private static final String TAG = "NativeMidiTestModule";
        private static final boolean DEBUG = true;

        private NativeMidiManager   mNativeMidiManager;

        public NativeMidiTestModule(int deviceType) {
            super(deviceType);
            mNativeMidiManager = new NativeMidiManager();

            // this call is just to keep the build from stripping out "endTest", because
            // it is only called from JNI.
            endTest(TESTSTATUS_NOTRUN);
        }

        protected void closePorts() {
            // NOP
        }

        @Override
        void startLoopbackTest(int testID) {
            synchronized (mTestLock) {
                mTestRunning = true;
                enableTestButtons(false);
            }

            if (DEBUG) {
                Log.i(TAG, "---- startLoopbackTest()");
            }

            mRunningTestID = testID;

            synchronized (mTestLock) {
                mTestStatus = TESTSTATUS_NOTRUN;
            }

            if (mIODevice.mSendDevInfo != null) {
                mMidiManager.openDevice(mIODevice.mSendDevInfo, new TestModuleOpenListener(), null);
            }

            startTimeoutHandler();
        }

        @Override
        boolean hasTestPassed() {
            int status;
            synchronized (mTestLock) {
                status = mTestStatus;
            }
            return status == TESTSTATUS_PASSED;
        }

        public void endTest(int endCode) {
            synchronized (mTestLock) {
                mTestRunning = false;
                mTestStatus = endCode;
            }
            if (endCode != TESTSTATUS_NOTRUN) {
                updateTestStateUI();
                enableTestButtons(true);
            }

            closePorts();
        }

        /**
         * Listens for MIDI device opens. Opens I/O ports and sends out the apriori
         * setup messages.
         */
        class TestModuleOpenListener implements MidiManager.OnDeviceOpenedListener {
            //
            // This is where the logical part of the test starts
            //
            @Override
            public void onDeviceOpened(MidiDevice device) {
                if (DEBUG) {
                    Log.i(TAG, "---- onDeviceOpened()");
                }
                mNativeMidiManager.startTest(NativeMidiTestModule.this, device,
                        mRunningTestID == TESTID_BTLOOPBACK);
            }
        }
    } /* class NativeMidiTestModule */

    /**
     * Test Module for Bluetooth Loopback.
     * This is a specialization of NativeMidiTestModule (which has the connections for the BL device
     * itself) with and added MidiIODevice object for the USB audio device which does the
     * "looping back".
     */
    private class BTMidiTestModule extends NativeMidiTestModule {
        private static final String TAG = "BTMidiTestModule";
        private MidiIODevice mUSBLoopbackDevice = new MidiIODevice(MidiDeviceInfo.TYPE_USB);

        public BTMidiTestModule() {
            super(MidiDeviceInfo.TYPE_BLUETOOTH);
        }

        @Override
        public void scanDevices(MidiDeviceInfo[] devInfos) {
            // (normal) Scan for BT MIDI device
            super.scanDevices(devInfos);
            // Find a USB Loopback Device
            mUSBLoopbackDevice.scanDevices(devInfos);
        }

        protected void closePorts() {
            super.closePorts();
            if (mUSBLoopbackDevice != null) {
                mUSBLoopbackDevice.closePorts();
            }
        }

        @Override
        void startLoopbackTest(int testID) {
            if (DEBUG) {
                Log.i(TAG, "---- startLoopbackTest()");
            }
            // Setup the USB Loopback Device
            mUSBLoopbackDevice.closePorts();

            if (mIODevice.mSendDevInfo != null) {
                mMidiManager.openDevice(
                        mUSBLoopbackDevice.mSendDevInfo, new USBLoopbackOpenListener(), null);
            }

            // Now start the test as usual
            super.startLoopbackTest(testID);
        }

        /**
         * We need this OnDeviceOpenedListener to open the USB-Loopback device
         */
        private class USBLoopbackOpenListener implements MidiManager.OnDeviceOpenedListener {
            @Override
            public void onDeviceOpened(MidiDevice device) {
                if (DEBUG) {
                    Log.i("USBLoopbackOpenListener", "---- onDeviceOpened()");
                }
                mUSBLoopbackDevice.openPorts(device, new USBMidiEchoReceiver());
            }
        } /* class USBLoopbackOpenListener */

        /**
         * MidiReceiver subclass for BlueTooth Loopback Test
         *
         * This class receives bytes from the USB Interface (presumably coming from the
         * Bluetooth MIDI peripheral) and echoes them back out (presumably to the Bluetooth
         * MIDI peripheral).
         */
        //TODO - This could be pulled out into a separate class and shared with the identical
        // code in MidiJavaTestActivity is we pass in the send port
        private class USBMidiEchoReceiver extends MidiReceiver {
            private int mTotalBytesEchoed;

            @Override
            public void onSend(byte[] msg, int offset, int count, long timestamp) throws IOException {
                mTotalBytesEchoed += count;
                if (DEBUG) {
                    Log.i(TAG, "---- USBMidiEchoReceiver.onSend() count:" + count +
                            " total:" + mTotalBytesEchoed);
                }
                if (mUSBLoopbackDevice.mSendPort == null) {
                    Log.e(TAG, "(native) mUSBLoopbackDevice.mSendPort is null");
                } else {
                    mUSBLoopbackDevice.mSendPort.onSend(msg, offset, count, timestamp);
                }
            }
        } /* class USBMidiEchoReceiver */
    } /* class BTMidiTestModule */
} /* class MidiNativeTestActivity */
