/*
 * Copyright (C) 2016 Google Inc.
 *
 * 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.googlecode.android_scripting.facade.bluetooth;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Service;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothInputDevice;
import android.bluetooth.BluetoothUuid;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.ParcelUuid;

import com.googlecode.android_scripting.Log;
import com.googlecode.android_scripting.facade.EventFacade;
import com.googlecode.android_scripting.facade.FacadeManager;
import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
import com.googlecode.android_scripting.rpc.Rpc;
import com.googlecode.android_scripting.rpc.RpcParameter;

public class BluetoothConnectionFacade extends RpcReceiver {

    private final Service mService;
    private final BluetoothAdapter mBluetoothAdapter;
    private final BluetoothPairingHelper mPairingHelper;
    private final Map<String, BroadcastReceiver> listeningDevices;
    private final EventFacade mEventFacade;

    private final IntentFilter mDiscoverConnectFilter;
    private final IntentFilter mPairingFilter;
    private final IntentFilter mBondFilter;
    private final IntentFilter mA2dpStateChangeFilter;
    private final IntentFilter mHidStateChangeFilter;
    private final IntentFilter mHspStateChangeFilter;

    private final Bundle mGoodNews;
    private final Bundle mBadNews;

    private BluetoothA2dpFacade mA2dpProfile;
    private BluetoothHidFacade mHidProfile;
    private BluetoothHspFacade mHspProfile;

    public BluetoothConnectionFacade(FacadeManager manager) {
        super(manager);
        mService = manager.getService();
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        mPairingHelper = new BluetoothPairingHelper();
        // Use a synchronized map to avoid racing problems
        listeningDevices = Collections.synchronizedMap(new HashMap<String, BroadcastReceiver>());

        mEventFacade = manager.getReceiver(EventFacade.class);
        mA2dpProfile = manager.getReceiver(BluetoothA2dpFacade.class);
        mHidProfile = manager.getReceiver(BluetoothHidFacade.class);
        mHspProfile = manager.getReceiver(BluetoothHspFacade.class);

        mDiscoverConnectFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        mDiscoverConnectFilter.addAction(BluetoothDevice.ACTION_UUID);
        mDiscoverConnectFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);

        mPairingFilter = new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST);
        mPairingFilter.addAction(BluetoothDevice.ACTION_CONNECTION_ACCESS_REQUEST);
        mPairingFilter.setPriority(999);

        mBondFilter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        mBondFilter.addAction(BluetoothDevice.ACTION_FOUND);
        mBondFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);

        mA2dpStateChangeFilter = new IntentFilter(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
        mHidStateChangeFilter = new IntentFilter(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);
        mHspStateChangeFilter = new IntentFilter(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);

        mGoodNews = new Bundle();
        mGoodNews.putBoolean("Status", true);
        mBadNews = new Bundle();
        mBadNews.putBoolean("Status", false);
    }

    private void unregisterCachedListener(String listenerId) {
        BroadcastReceiver listener = listeningDevices.remove(listenerId);
        if (listener != null) {
            mService.unregisterReceiver(listener);
        }        
    }

    /**
     * Connect to a specific device upon its discovery
     */
    public class DiscoverConnectReceiver extends BroadcastReceiver {
        private final String mDeviceID;
        private BluetoothDevice mDevice;

        /**
         * Constructor
         *
         * @param deviceID Either the device alias name or mac address.
         * @param bond If true, bond the device only.
         */
        public DiscoverConnectReceiver(String deviceID) {
            super();
            mDeviceID = deviceID;
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            // The specified device is found.
            if (action.equals(BluetoothDevice.ACTION_FOUND)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if (BluetoothFacade.deviceMatch(device, mDeviceID)) {
                    Log.d("Found device " + device.getAliasName() + " for connection.");
                    mBluetoothAdapter.cancelDiscovery();
                    mDevice = device;
                }
            // After discovery stops.
            } else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
                if (mDevice == null) {
                    Log.d("Device " + mDeviceID + " not discovered.");
                    mEventFacade.postEvent("Bond" + mDeviceID, mBadNews);
                    return;
                }
                boolean status = mDevice.fetchUuidsWithSdp();
                Log.d("Initiated ACL connection: " + status);
            } else if (action.equals(BluetoothDevice.ACTION_UUID)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if (BluetoothFacade.deviceMatch(device, mDeviceID)) {
                    Log.d("Initiating connections.");
                    connectProfile(device, mDeviceID);
                    mService.unregisterReceiver(listeningDevices.remove("Connect" + mDeviceID));
                }
            }
        }
    }

    /**
     * Connect to a specific device upon its discovery
     */
    public class DiscoverBondReceiver extends BroadcastReceiver {
        private final String mDeviceID;
        private BluetoothDevice mDevice = null;
        private boolean started = false;

        /**
         * Constructor
         *
         * @param deviceID Either the device alias name or Mac address.
         */
        public DiscoverBondReceiver(String deviceID) {
            super();
            mDeviceID = deviceID;
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            // The specified device is found.
            if (action.equals(BluetoothDevice.ACTION_FOUND)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if (BluetoothFacade.deviceMatch(device, mDeviceID)) {
                    Log.d("Found device " + device.getAliasName() + " for connection.");
                    mBluetoothAdapter.cancelDiscovery();
                    mDevice = device;
                }
            // After discovery stops.
            } else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
                if (mDevice == null) {
                    Log.d("Device " + mDeviceID + " was not discovered.");
                    mEventFacade.postEvent("Bond", mBadNews);
                    return;
                }
                // Attempt to initiate bonding.
                if (!started) {
                    Log.d("Bond with " + mDevice.getAliasName());
                    if (mDevice.createBond()) {
                        started = true;
                        Log.d("Bonding started.");
                    } else {
                        Log.e("Failed to bond with " + mDevice.getAliasName());
                        mEventFacade.postEvent("Bond", mBadNews);
                        mService.unregisterReceiver(listeningDevices.remove("Bond" + mDeviceID));
                    }
                }
            } else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
                Log.d("Bond state changing.");
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if (BluetoothFacade.deviceMatch(device, mDeviceID)) {
                    int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1);
                    Log.d("New state is " + state);
                    if (state == BluetoothDevice.BOND_BONDED) {
                        Log.d("Bonding with " + mDeviceID + " successful.");
                        mEventFacade.postEvent("Bond" + mDeviceID, mGoodNews);
                        mService.unregisterReceiver(listeningDevices.remove("Bond" + mDeviceID));
                    }
                }
            }
        }
    }

    public class ConnectStateChangeReceiver extends BroadcastReceiver {
        private final String mDeviceID;

        public ConnectStateChangeReceiver(String deviceID) {
            mDeviceID = deviceID;
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            // Check if received the specified device
            if (!BluetoothFacade.deviceMatch(device, mDeviceID)) {
                return;
            }
            if (action.equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)) {
                int state = intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, -1);
                if (state == BluetoothA2dp.STATE_CONNECTED) {
                	Bundle a2dpGoodNews = (Bundle) mGoodNews.clone();
                	a2dpGoodNews.putString("Type", "a2dp");
                    mEventFacade.postEvent("A2dpConnect" + mDeviceID, a2dpGoodNews);
                    unregisterCachedListener("A2dpConnecting" + mDeviceID);
                } else if (state == BluetoothA2dp.STATE_CONNECTING) {
                }
            }else if (action.equals(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED)) {
                int state = intent.getIntExtra(BluetoothInputDevice.EXTRA_STATE, -1);
                if (state == BluetoothInputDevice.STATE_CONNECTED) {
                    mEventFacade.postEvent("HidConnect" + mDeviceID, mGoodNews);
                    unregisterCachedListener("HidConnecting" + mDeviceID);
                }
            } else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
                int state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, -1);
                if (state == BluetoothHeadset.STATE_CONNECTED) {
                    mEventFacade.postEvent("HspConnect" + mDeviceID, mGoodNews);
                    unregisterCachedListener("HspConnecting" + mDeviceID);
                }
            }
        }
    }

    private void connectProfile(BluetoothDevice device, String deviceID) {
        mService.registerReceiver(mPairingHelper, mPairingFilter);
        ParcelUuid[] deviceUuids = device.getUuids();
        Log.d("Device uuid is " + deviceUuids);
        if (deviceUuids == null) {
        	mEventFacade.postEvent("Connect", mBadNews);
        }
        if (BluetoothUuid.containsAnyUuid(BluetoothA2dpFacade.SINK_UUIDS, deviceUuids)) {
            Log.d("Connecting to " + device.getAliasName());
            boolean status = mA2dpProfile.a2dpConnect(device);
            if (status) {
                Log.d("Connecting A2dp...");
                ConnectStateChangeReceiver receiver = new ConnectStateChangeReceiver(deviceID);
                mService.registerReceiver(receiver, mA2dpStateChangeFilter);
                listeningDevices.put("A2dpConnecting" + deviceID, receiver);
            } else {
                Log.d("Failed starting A2dp connection.");
                Bundle a2dpBadNews = (Bundle) mBadNews.clone();
                a2dpBadNews.putString("Type", "a2dp");
                mEventFacade.postEvent("Connect", a2dpBadNews);
            }
        }
        if (BluetoothUuid.containsAnyUuid(BluetoothHidFacade.UUIDS, deviceUuids)) {
            boolean status = mHidProfile.hidConnect(device);
            if (status) {
                Log.d("Connecting Hid...");
                ConnectStateChangeReceiver receiver = new ConnectStateChangeReceiver(deviceID);
                mService.registerReceiver(receiver, mHidStateChangeFilter);
                listeningDevices.put("HidConnecting" + deviceID, receiver);
            } else {
                Log.d("Failed starting Hid connection.");
                mEventFacade.postEvent("HidConnect" + deviceID, mBadNews);
            }
        }
        if (BluetoothUuid.containsAnyUuid(BluetoothHspFacade.UUIDS, deviceUuids)) {
            boolean status = mHspProfile.hspConnect(device);
            if (status) {
                Log.d("Connecting Hsp...");
                ConnectStateChangeReceiver receiver = new ConnectStateChangeReceiver(deviceID);
                mService.registerReceiver(receiver, mHspStateChangeFilter);
                listeningDevices.put("HspConnecting" + deviceID, receiver);
            } else {
                Log.d("Failed starting Hsp connection.");
                mEventFacade.postEvent("HspConnect" + deviceID, mBadNews);
            }
        }
        mService.unregisterReceiver(mPairingHelper);
    }

    @Rpc(description = "Start intercepting all bluetooth connection pop-ups.")
    public void bluetoothStartPairingHelper() {
        mService.registerReceiver(mPairingHelper, mPairingFilter);
    }

    @Rpc(description = "Return a list of devices connected through bluetooth")
    public List<BluetoothDevice> bluetoothGetConnectedDevices() {
        ArrayList<BluetoothDevice> results = new ArrayList<BluetoothDevice>();
        for (BluetoothDevice bd : mBluetoothAdapter.getBondedDevices()) {
            if (bd.isConnected()) {
                results.add(bd);
            }
        }
        return results;
    }

    @Rpc(description = "Return true if a bluetooth device is connected.")
    public Boolean bluetoothIsDeviceConnected(String deviceID) {
        for (BluetoothDevice bd : mBluetoothAdapter.getBondedDevices()) {
            if (BluetoothFacade.deviceMatch(bd, deviceID)) {
                return bd.isConnected();
            }
        }
        return false;
    }

    @Rpc(description = "Connect to a specified device once it's discovered.",
         returns = "Whether discovery started successfully.")
    public Boolean bluetoothDiscoverAndConnect(
            @RpcParameter(name = "deviceID",
                          description = "Name or MAC address of a bluetooth device.")
            String deviceID) {
        mBluetoothAdapter.cancelDiscovery();
        if (listeningDevices.containsKey(deviceID)) {
            Log.d("This device is already in the process of discovery and connecting.");
            return true;
        }
        DiscoverConnectReceiver receiver = new DiscoverConnectReceiver(deviceID);
        listeningDevices.put("Connect" + deviceID, receiver);
        mService.registerReceiver(receiver, mDiscoverConnectFilter);
        return mBluetoothAdapter.startDiscovery();
    }

    @Rpc(description = "Bond to a specified device once it's discovered.",
         returns = "Whether discovery started successfully. ")
    public Boolean bluetoothDiscoverAndBond(
            @RpcParameter(name = "deviceID",
                          description = "Name or MAC address of a bluetooth device.")
            String deviceID) {
        mBluetoothAdapter.cancelDiscovery();
        if (listeningDevices.containsKey(deviceID)) {
            Log.d("This device is already in the process of discovery and bonding.");
            return true;
        }
        if (BluetoothFacade.deviceExists(mBluetoothAdapter.getBondedDevices(), deviceID)) {
            Log.d("Device " + deviceID + " is already bonded.");
            mEventFacade.postEvent("Bond" + deviceID, mGoodNews);
            return true;
        }
        DiscoverBondReceiver receiver = new DiscoverBondReceiver(deviceID);
        if (listeningDevices.containsKey("Bond" + deviceID)) {
            mService.unregisterReceiver(listeningDevices.remove("Bond" + deviceID));
        }
        listeningDevices.put("Bond" + deviceID, receiver);
        mService.registerReceiver(receiver, mBondFilter);
        Log.d("Start discovery for bonding.");
        return mBluetoothAdapter.startDiscovery();
    }

    @Rpc(description = "Unbond a device.",
         returns = "Whether the device was successfully unbonded.")
    public Boolean bluetoothUnbond(
            @RpcParameter(name = "deviceID",
                          description = "Name or MAC address of a bluetooth device.")
            String deviceID) throws Exception {
        BluetoothDevice mDevice = BluetoothFacade.getDevice(mBluetoothAdapter.getBondedDevices(),
                deviceID);
        return mDevice.removeBond();
    }

    @Rpc(description = "Connect to a device that is already bonded.")
    public void bluetoothConnectBonded(
            @RpcParameter(name = "deviceID",
                          description = "Name or MAC address of a bluetooth device.")
            String deviceID) throws Exception {
        BluetoothDevice mDevice = BluetoothFacade.getDevice(mBluetoothAdapter.getBondedDevices(),
                deviceID);
        connectProfile(mDevice, deviceID);
    }

    @Override
    public void shutdown() {
        for(BroadcastReceiver receiver : listeningDevices.values()) {
            mService.unregisterReceiver(receiver);
        }
        listeningDevices.clear();
        mService.unregisterReceiver(mPairingHelper);
    }
}
