/*
 * Copyright (C) 2014 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.media.midi;

import android.annotation.RequiresFeature;
import android.annotation.SystemService;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.IBinder;
import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
import android.util.Log;

import java.util.concurrent.ConcurrentHashMap;

/**
 * This class is the public application interface to the MIDI service.
 */
@SystemService(Context.MIDI_SERVICE)
@RequiresFeature(PackageManager.FEATURE_MIDI)
public final class MidiManager {
    private static final String TAG = "MidiManager";

    /**
     * Intent for starting BluetoothMidiService
     * @hide
     */
    public static final String BLUETOOTH_MIDI_SERVICE_INTENT =
                "android.media.midi.BluetoothMidiService";

    /**
     * BluetoothMidiService package name
     * @hide
     */
    public static final String BLUETOOTH_MIDI_SERVICE_PACKAGE = "com.android.bluetoothmidiservice";

    /**
     * BluetoothMidiService class name
     * @hide
     */
    public static final String BLUETOOTH_MIDI_SERVICE_CLASS =
                "com.android.bluetoothmidiservice.BluetoothMidiService";

    private final IMidiManager mService;
    private final IBinder mToken = new Binder();

    private ConcurrentHashMap<DeviceCallback,DeviceListener> mDeviceListeners =
        new ConcurrentHashMap<DeviceCallback,DeviceListener>();

    // Binder stub for receiving device notifications from MidiService
    private class DeviceListener extends IMidiDeviceListener.Stub {
        private final DeviceCallback mCallback;
        private final Handler mHandler;

        public DeviceListener(DeviceCallback callback, Handler handler) {
            mCallback = callback;
            mHandler = handler;
        }

        @Override
        public void onDeviceAdded(MidiDeviceInfo device) {
            if (mHandler != null) {
                final MidiDeviceInfo deviceF = device;
                mHandler.post(new Runnable() {
                        @Override public void run() {
                            mCallback.onDeviceAdded(deviceF);
                        }
                    });
            } else {
                mCallback.onDeviceAdded(device);
            }
        }

        @Override
        public void onDeviceRemoved(MidiDeviceInfo device) {
            if (mHandler != null) {
                final MidiDeviceInfo deviceF = device;
                mHandler.post(new Runnable() {
                        @Override public void run() {
                            mCallback.onDeviceRemoved(deviceF);
                        }
                    });
            } else {
                mCallback.onDeviceRemoved(device);
            }
        }

        @Override
        public void onDeviceStatusChanged(MidiDeviceStatus status) {
            if (mHandler != null) {
                final MidiDeviceStatus statusF = status;
                mHandler.post(new Runnable() {
                        @Override public void run() {
                            mCallback.onDeviceStatusChanged(statusF);
                        }
                    });
            } else {
                mCallback.onDeviceStatusChanged(status);
            }
        }
    }

    /**
     * Callback class used for clients to receive MIDI device added and removed notifications
     */
    public static class DeviceCallback {
        /**
         * Called to notify when a new MIDI device has been added
         *
         * @param device a {@link MidiDeviceInfo} for the newly added device
         */
        public void onDeviceAdded(MidiDeviceInfo device) {
        }

        /**
         * Called to notify when a MIDI device has been removed
         *
         * @param device a {@link MidiDeviceInfo} for the removed device
         */
        public void onDeviceRemoved(MidiDeviceInfo device) {
        }

        /**
         * Called to notify when the status of a MIDI device has changed
         *
         * @param status a {@link MidiDeviceStatus} for the changed device
         */
        public void onDeviceStatusChanged(MidiDeviceStatus status) {
        }
    }

    /**
     * Listener class used for receiving the results of {@link #openDevice} and
     * {@link #openBluetoothDevice}
     */
    public interface OnDeviceOpenedListener {
        /**
         * Called to respond to a {@link #openDevice} request
         *
         * @param device a {@link MidiDevice} for opened device, or null if opening failed
         */
        abstract public void onDeviceOpened(MidiDevice device);
    }

    /**
     * @hide
     */
    public MidiManager(IMidiManager service) {
        mService = service;
    }

    /**
     * Registers a callback to receive notifications when MIDI devices are added and removed.
     *
     * The {@link  DeviceCallback#onDeviceStatusChanged} method will be called immediately
     * for any devices that have open ports. This allows applications to know which input
     * ports are already in use and, therefore, unavailable.
     *
     * Applications should call {@link #getDevices} before registering the callback
     * to get a list of devices already added.
     *
     * @param callback a {@link DeviceCallback} for MIDI device notifications
     * @param handler The {@link android.os.Handler Handler} that will be used for delivering the
     *                device notifications. If handler is null, then the thread used for the
     *                callback is unspecified.
     */
    public void registerDeviceCallback(DeviceCallback callback, Handler handler) {
        DeviceListener deviceListener = new DeviceListener(callback, handler);
        try {
            mService.registerListener(mToken, deviceListener);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
        mDeviceListeners.put(callback, deviceListener);
    }

    /**
     * Unregisters a {@link DeviceCallback}.
      *
     * @param callback a {@link DeviceCallback} to unregister
     */
    public void unregisterDeviceCallback(DeviceCallback callback) {
        DeviceListener deviceListener = mDeviceListeners.remove(callback);
        if (deviceListener != null) {
            try {
                mService.unregisterListener(mToken, deviceListener);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
    }

    /**
     * Gets the list of all connected MIDI devices.
     *
     * @return an array of all MIDI devices
     */
    public MidiDeviceInfo[] getDevices() {
        try {
           return mService.getDevices();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    private void sendOpenDeviceResponse(final MidiDevice device,
            final OnDeviceOpenedListener listener, Handler handler) {
        if (handler != null) {
            handler.post(new Runnable() {
                    @Override public void run() {
                        listener.onDeviceOpened(device);
                    }
                });
        } else {
            listener.onDeviceOpened(device);
        }
    }

    /**
     * Opens a MIDI device for reading and writing.
     *
     * @param deviceInfo a {@link android.media.midi.MidiDeviceInfo} to open
     * @param listener a {@link MidiManager.OnDeviceOpenedListener} to be called
     *                 to receive the result
     * @param handler the {@link android.os.Handler Handler} that will be used for delivering
     *                the result. If handler is null, then the thread used for the
     *                listener is unspecified.
     */
    public void openDevice(MidiDeviceInfo deviceInfo, OnDeviceOpenedListener listener,
            Handler handler) {
        final MidiDeviceInfo deviceInfoF = deviceInfo;
        final OnDeviceOpenedListener listenerF = listener;
        final Handler handlerF = handler;

        IMidiDeviceOpenCallback callback = new IMidiDeviceOpenCallback.Stub() {
            @Override
            public void onDeviceOpened(IMidiDeviceServer server, IBinder deviceToken) {
                MidiDevice device;
                if (server != null) {
                    device = new MidiDevice(deviceInfoF, server, mService, mToken, deviceToken);
                } else {
                    device = null;
                }
                sendOpenDeviceResponse(device, listenerF, handlerF);
            }
        };

        try {
            mService.openDevice(mToken, deviceInfo, callback);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Opens a Bluetooth MIDI device for reading and writing.
     *
     * @param bluetoothDevice a {@link android.bluetooth.BluetoothDevice} to open as a MIDI device
     * @param listener a {@link MidiManager.OnDeviceOpenedListener} to be called to receive the
     * result
     * @param handler the {@link android.os.Handler Handler} that will be used for delivering
     *                the result. If handler is null, then the thread used for the
     *                listener is unspecified.
     */
    public void openBluetoothDevice(BluetoothDevice bluetoothDevice,
            OnDeviceOpenedListener listener, Handler handler) {
        final OnDeviceOpenedListener listenerF = listener;
        final Handler handlerF = handler;

        IMidiDeviceOpenCallback callback = new IMidiDeviceOpenCallback.Stub() {
            @Override
            public void onDeviceOpened(IMidiDeviceServer server, IBinder deviceToken) {
                MidiDevice device = null;
                if (server != null) {
                    try {
                        // fetch MidiDeviceInfo from the server
                        MidiDeviceInfo deviceInfo = server.getDeviceInfo();
                        device = new MidiDevice(deviceInfo, server, mService, mToken, deviceToken);
                    } catch (RemoteException e) {
                        Log.e(TAG, "remote exception in getDeviceInfo()");
                    }
                }
                sendOpenDeviceResponse(device, listenerF, handlerF);
            }
        };

        try {
            mService.openBluetoothDevice(mToken, bluetoothDevice, callback);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /** @hide */
    public MidiDeviceServer createDeviceServer(MidiReceiver[] inputPortReceivers,
            int numOutputPorts, String[] inputPortNames, String[] outputPortNames,
            Bundle properties, int type, MidiDeviceServer.Callback callback) {
        try {
            MidiDeviceServer server = new MidiDeviceServer(mService, inputPortReceivers,
                    numOutputPorts, callback);
            MidiDeviceInfo deviceInfo = mService.registerDeviceServer(server.getBinderInterface(),
                    inputPortReceivers.length, numOutputPorts, inputPortNames, outputPortNames,
                    properties, type);
            if (deviceInfo == null) {
                Log.e(TAG, "registerVirtualDevice failed");
                return null;
            }
            return server;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
}
