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

import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothAdapter.LeScanCallback;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanFilter.Builder;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.os.Bundle;
import android.os.ParcelUuid;

import com.googlecode.android_scripting.Log;
import com.googlecode.android_scripting.MainThread;
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.RpcOptional;
import com.googlecode.android_scripting.rpc.RpcParameter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.Callable;

/**
 * BluetoothLe Scan functions.
 */

public class BluetoothLeScanFacade extends RpcReceiver {

    private final EventFacade mEventFacade;

    private BluetoothAdapter mBluetoothAdapter;
    private static int ScanCallbackCount;
    private static int FilterListCount;
    private static int LeScanCallbackCount;
    private static int ScanSettingsCount;
    private final Service mService;
    private final BluetoothLeScanner mScanner;
    private android.bluetooth.le.ScanSettings.Builder mScanSettingsBuilder;
    private Builder mScanFilterBuilder;
    private final HashMap<Integer, myScanCallback> mScanCallbackList;
    private final HashMap<Integer, myLeScanCallback> mLeScanCallbackList;
    private final HashMap<Integer, ArrayList<ScanFilter>> mScanFilterList;
    private final HashMap<Integer, ScanSettings> mScanSettingsList;

    public BluetoothLeScanFacade(FacadeManager manager) {
        super(manager);
        mService = manager.getService();
        mBluetoothAdapter = MainThread.run(mService,
                new Callable<BluetoothAdapter>() {
                    @Override
                    public BluetoothAdapter call() throws Exception {
                        return BluetoothAdapter.getDefaultAdapter();
                    }
                });
        mScanner = mBluetoothAdapter.getBluetoothLeScanner();
        mEventFacade = manager.getReceiver(EventFacade.class);
        mScanFilterList = new HashMap<Integer, ArrayList<ScanFilter>>();
        mLeScanCallbackList = new HashMap<Integer, myLeScanCallback>();
        mScanSettingsList = new HashMap<Integer, ScanSettings>();
        mScanCallbackList = new HashMap<Integer, myScanCallback>();
        mScanFilterBuilder = new Builder();
        mScanSettingsBuilder = new android.bluetooth.le.ScanSettings.Builder();
    }

    /**
     * Constructs a myScanCallback obj and returns its index
     *
     * @return Integer myScanCallback.index
     */
    @Rpc(description = "Generate a new myScanCallback Object")
    public Integer bleGenScanCallback() {
        ScanCallbackCount += 1;
        int index = ScanCallbackCount;
        myScanCallback mScan = new myScanCallback(index);
        mScanCallbackList.put(mScan.index, mScan);
        return mScan.index;
    }

    /**
     * Constructs a myLeScanCallback obj and returns its index
     *
     * @return Integer myScanCallback.index
     */
    @Rpc(description = "Generate a new myScanCallback Object")
    public Integer bleGenLeScanCallback() {
        LeScanCallbackCount += 1;
        int index = LeScanCallbackCount;
        myLeScanCallback mScan = new myLeScanCallback(index);
        mLeScanCallbackList.put(mScan.index, mScan);
        return mScan.index;
    }

    /**
     * Constructs a new filter list array and returns its index
     *
     * @return Integer index
     */
    @Rpc(description = "Generate a new Filter list")
    public Integer bleGenFilterList() {
        FilterListCount += 1;
        int index = FilterListCount;
        mScanFilterList.put(index, new ArrayList<ScanFilter>());
        return index;
    }

    /**
     * Constructs a new filter list array and returns its index
     *
     * @return Integer index
     */
    @Rpc(description = "Generate a new Filter list")
    public Integer bleBuildScanFilter(
            @RpcParameter(name = "filterIndex")
            Integer filterIndex
            ) {
        mScanFilterList.get(filterIndex).add(mScanFilterBuilder.build());
        mScanFilterBuilder = new Builder();
        return mScanFilterList.get(filterIndex).size()-1;
    }

    /**
     * Constructs a new scan setting and returns its index
     *
     * @return Integer index
     */
    @Rpc(description = "Generate a new scan settings Object")
    public Integer bleBuildScanSetting() {
        ScanSettingsCount += 1;
        int index = ScanSettingsCount;
        mScanSettingsList.put(index, mScanSettingsBuilder.build());
        mScanSettingsBuilder = new android.bluetooth.le.ScanSettings.Builder();
        return index;
    }

    /**
     * Stops a ble scan
     *
     * @param index the id of the myScan whose ScanCallback to stop
     * @throws Exception
     */
    @Rpc(description = "Stops an ongoing ble advertisement scan")
    public void bleStopBleScan(
            @RpcParameter(name = "index")
            Integer index) throws Exception {
        Log.d("bluetooth_le_scan mScanCallback " + index);
        if (mScanCallbackList.get(index) != null) {
            myScanCallback mScanCallback = mScanCallbackList.get(index);
            mScanner.stopScan(mScanCallback);
        } else {
            throw new Exception("Invalid index input:" + Integer.toString(index));
        }
    }

    /**
     * Stops a classic ble scan
     *
     * @param index the id of the myScan whose LeScanCallback to stop
     * @throws Exception
     */
    @Rpc(description = "Stops an ongoing classic ble scan")
    public void bleStopClassicBleScan(
            @RpcParameter(name = "index")
            Integer index) throws Exception {
        Log.d("bluetooth_le_scan mLeScanCallback " + index);
        if (mLeScanCallbackList.get(index) != null) {
            myLeScanCallback mLeScanCallback = mLeScanCallbackList.get(index);
            mBluetoothAdapter.stopLeScan(mLeScanCallback);
        } else {
            throw new Exception("Invalid index input:" + Integer.toString(index));
        }
    }

    /**
     * Starts a ble scan
     *
     * @param index the id of the myScan whose ScanCallback to start
     * @throws Exception
     */
    @Rpc(description = "Starts a ble advertisement scan")
    public void bleStartBleScan(
            @RpcParameter(name = "filterListIndex")
            Integer filterListIndex,
            @RpcParameter(name = "scanSettingsIndex")
            Integer scanSettingsIndex,
            @RpcParameter(name = "callbackIndex")
            Integer callbackIndex
            ) throws Exception {
        Log.d("bluetooth_le_scan starting a background scan");
        ArrayList<ScanFilter> mScanFilters = new ArrayList<ScanFilter>();
        mScanFilters.add(new ScanFilter.Builder().build());
        ScanSettings mScanSettings = new ScanSettings.Builder().build();
        if (mScanFilterList.get(filterListIndex) != null) {
            mScanFilters = mScanFilterList.get(filterListIndex);
        } else {
            throw new Exception("Invalid filterListIndex input:"
                    + Integer.toString(filterListIndex));
        }
        if (mScanSettingsList.get(scanSettingsIndex) != null) {
            mScanSettings = mScanSettingsList.get(scanSettingsIndex);
        } else if (!mScanSettingsList.isEmpty()) {
            throw new Exception("Invalid scanSettingsIndex input:"
                    + Integer.toString(scanSettingsIndex));
        }
        if (mScanCallbackList.get(callbackIndex) != null) {
            mScanner.startScan(mScanFilters, mScanSettings,
                    mScanCallbackList.get(callbackIndex));
        } else {
            throw new Exception("Invalid filterListIndex input:"
                    + Integer.toString(filterListIndex));
        }
    }

    /**
     * Starts a classic ble scan
     *
     * @param index the id of the myScan whose ScanCallback to start
     * @throws Exception
     */
    @Rpc(description = "Starts a classic ble advertisement scan")
    public boolean bleStartClassicBleScan(
            @RpcParameter(name = "leCallbackIndex")
            Integer leCallbackIndex
            ) throws Exception {
        Log.d("bluetooth_le_scan starting a background scan");
        boolean result = false;
        if (mLeScanCallbackList.get(leCallbackIndex) != null) {
            result = mBluetoothAdapter.startLeScan(
                    mLeScanCallbackList.get(leCallbackIndex));
        } else {
            throw new Exception("Invalid leCallbackIndex input:"
                    + Integer.toString(leCallbackIndex));
        }
        return result;
    }

    /**
     * Starts a classic ble scan with service Uuids
     *
     * @param index the id of the myScan whose ScanCallback to start
     * @throws Exception
     */
    @Rpc(description = "Starts a classic ble advertisement scan with service Uuids")
    public boolean bleStartClassicBleScanWithServiceUuids(
            @RpcParameter(name = "leCallbackIndex")
            Integer leCallbackIndex,
            @RpcParameter(name = "serviceUuids")
            String[] serviceUuidList
            ) throws Exception {
        Log.d("bluetooth_le_scan starting a background scan");
        UUID[] serviceUuids = new UUID[serviceUuidList.length];
        for (int i = 0; i < serviceUuidList.length; i++) {
            serviceUuids[i] = UUID.fromString(serviceUuidList[i]);
        }
        boolean result = false;
        if (mLeScanCallbackList.get(leCallbackIndex) != null) {
            result = mBluetoothAdapter.startLeScan(serviceUuids,
                    mLeScanCallbackList.get(leCallbackIndex));
        } else {
            throw new Exception("Invalid leCallbackIndex input:"
                    + Integer.toString(leCallbackIndex));
        }
        return result;
    }

    /**
     * Trigger onBatchScanResults
     *
     * @throws Exception
     */
    @Rpc(description = "Gets the results of the ble ScanCallback")
    public void bleFlushPendingScanResults(
            @RpcParameter(name = "callbackIndex")
            Integer callbackIndex
            ) throws Exception {
        if (mScanCallbackList.get(callbackIndex) != null) {
            mBluetoothAdapter
                    .getBluetoothLeScanner().flushPendingScanResults(
                            mScanCallbackList.get(callbackIndex));
        } else {
            throw new Exception("Invalid callbackIndex input:"
                    + Integer.toString(callbackIndex));
        }
    }

    /**
     * Set scanSettings for ble scan. Note: You have to set all variables at once.
     *
     * @param callbackType Bluetooth LE scan callback type
     * @param reportDelaySeconds Time of delay for reporting the scan result
     * @param scanMode Bluetooth LE scan mode.
     * @param scanResultType Bluetooth LE scan result type
     * @throws Exception
     */

    /**
     * Set the scan setting's callback type
     * @param callbackType Bluetooth LE scan callback type
     */
    @Rpc(description = "Set the scan setting's callback type")
    public void bleSetScanSettingsCallbackType(
            @RpcParameter(name = "callbackType")
            Integer callbackType) {
        mScanSettingsBuilder.setCallbackType(callbackType);
    }

    /**
     * Set the scan setting's report delay millis
     * @param reportDelayMillis Time of delay for reporting the scan result
     */
    @Rpc(description = "Set the scan setting's report delay millis")
    public void bleSetScanSettingsReportDelayMillis(
            @RpcParameter(name = "reportDelayMillis")
            Long reportDelayMillis) {
        mScanSettingsBuilder.setReportDelay(reportDelayMillis);
    }

    /**
     * Set the scan setting's scan mode
     * @param scanMode Bluetooth LE scan mode.
     */
    @Rpc(description = "Set the scan setting's scan mode")
    public void bleSetScanSettingsScanMode(
            @RpcParameter(name = "scanMode")
            Integer scanMode) {
        mScanSettingsBuilder.setScanMode(scanMode);
    }

    /**
     * Set the scan setting's legacy mode
     * @param legacy Wether scan is legacy.
     */
    @Rpc(description = "Set the scan setting's legacy mode")
    public void bleSetScanSettingsLegacy(
            @RpcParameter(name = "legacy")
            Boolean legacy) {
        mScanSettingsBuilder.setLegacy(legacy);
    }

    /**
     * Set the scan setting's phy mode
     * @param phy
     */
    @Rpc(description = "Set the scan setting's phy mode")
    public void bleSetScanSettingsPhy(
            @RpcParameter(name = "phy")
            Integer phy) {
        mScanSettingsBuilder.setPhy(phy);
    }

    /**
     * Set the scan setting's scan result type
     * @param scanResultType Bluetooth LE scan result type
     */
    @Rpc(description = "Set the scan setting's scan result type")
    public void bleSetScanSettingsResultType(
            @RpcParameter(name = "scanResultType")
            Integer scanResultType) {
        mScanSettingsBuilder.setScanResultType(scanResultType);
    }
    /**
     * Get ScanSetting's callback type
     *
     * @param index the ScanSetting object to use
     * @return the ScanSetting's callback type
     * @throws Exception
     */
    @Rpc(description = "Get ScanSetting's callback type")
    public Integer bleGetScanSettingsCallbackType(
            @RpcParameter(name = "index")
            Integer index
            ) throws Exception {
        if (mScanSettingsList.get(index) != null) {
            ScanSettings mScanSettings = mScanSettingsList.get(index);
            return mScanSettings.getCallbackType();
        } else {
            throw new Exception("Invalid index input:" + Integer.toString(index));
        }
    }

    /**
     * Get ScanSetting's report delay in milli seconds
     *
     * @param index the ScanSetting object to useSystemClock
     * @return the ScanSetting's report delay in milliseconds
     * @throws Exception
     */
    @Rpc(description = "Get ScanSetting's report delay milliseconds")
    public Long bleGetScanSettingsReportDelayMillis(
            @RpcParameter(name = "index")
            Integer index) throws Exception {
        if (mScanSettingsList.get(index) != null) {
            ScanSettings mScanSettings = mScanSettingsList.get(index);
            return mScanSettings.getReportDelayMillis();
        } else {
            throw new Exception("Invalid index input:" + Integer.toString(index));
        }
    }

    /**
     * Get ScanSetting's scan mode
     *
     * @param index the ScanSetting object to use
     * @return the ScanSetting's scan mode
     * @throws Exception
     */
    @Rpc(description = "Get ScanSetting's scan mode")
    public Integer bleGetScanSettingsScanMode(
            @RpcParameter(name = "index")
            Integer index) throws Exception {
        if (mScanSettingsList.get(index) != null) {
            ScanSettings mScanSettings = mScanSettingsList.get(index);
            return mScanSettings.getScanMode();
        } else {
            throw new Exception("Invalid index input:" + Integer.toString(index));
        }
    }

    /**
     * Get ScanSetting's scan result type
     *
     * @param index the ScanSetting object to use
     * @return the ScanSetting's scan result type
     * @throws Exception
     */
    @Rpc(description = "Get ScanSetting's scan result type")
    public Integer bleGetScanSettingsScanResultType(
            @RpcParameter(name = "index")
            Integer index) throws Exception {
        if (mScanSettingsList.get(index) != null) {
            ScanSettings mScanSettings = mScanSettingsList.get(index);
            return mScanSettings.getScanResultType();
        } else {
            throw new Exception("Invalid index input:"
                    +    Integer.toString(index));
        }
    }

    /**
     * Get ScanFilter's Manufacturer Id
     *
     * @param index the ScanFilter object to use
     * @return the ScanFilter's manufacturer id
     * @throws Exception
     */
    @Rpc(description = "Get ScanFilter's Manufacturer Id")
    public Integer bleGetScanFilterManufacturerId(
            @RpcParameter(name = "index")
            Integer index,
            @RpcParameter(name = "filterIndex")
            Integer filterIndex)
            throws Exception {
        if (mScanFilterList.get(index) != null) {
            if (mScanFilterList.get(index).get(filterIndex) != null) {
                return mScanFilterList.get(index)
                        .get(filterIndex).getManufacturerId();
            } else {
                throw new Exception("Invalid filterIndex input:"
                        + Integer.toString(filterIndex));
            }
        } else {
            throw new Exception("Invalid index input:"
                    + Integer.toString(index));
        }
    }

    /**
     * Get ScanFilter's device address
     *
     * @param index the ScanFilter object to use
     * @return the ScanFilter's device address
     * @throws Exception
     */
    @Rpc(description = "Get ScanFilter's device address")
    public String bleGetScanFilterDeviceAddress(
            @RpcParameter(name = "index")
            Integer index,
            @RpcParameter(name = "filterIndex")
            Integer filterIndex)
            throws Exception {
        if (mScanFilterList.get(index) != null) {
            if (mScanFilterList.get(index).get(filterIndex) != null) {
                return mScanFilterList.get(index).get(
                        filterIndex).getDeviceAddress();
            } else {
                throw new Exception("Invalid filterIndex input:"
                        + Integer.toString(filterIndex));
            }
        } else {
            throw new Exception("Invalid index input:"
                    + Integer.toString(index));
        }
    }

    /**
     * Get ScanFilter's device address type
     *
     * @param index the ScanFilter object to use
     * @return the ScanFilter's device address type
     * @throws Exception
     */
    @Rpc(description = "Get ScanFilter's device address type")
    public Integer bleGetScanFilterAddressType(
            @RpcParameter(name = "index")
                    Integer index,
            @RpcParameter(name = "filterIndex")
                    Integer filterIndex)
            throws Exception {
        if (mScanFilterList.get(index) != null) {
            if (mScanFilterList.get(index).get(filterIndex) != null) {
                return mScanFilterList.get(index).get(
                        filterIndex).getAddressType();
            } else {
                throw new Exception("Invalid filterIndex input:" + filterIndex);
            }
        } else {
            throw new Exception("Invalid index input:" + index);
        }
    }

    /**
     * Get ScanFilter's irk
     *
     * @param index the ScanFilter object to use
     * @return the ScanFilter's irk
     * @throws Exception
     */
    @Rpc(description = "Get ScanFilter's irk")
    public byte[] bleGetScanFilterIrk(
            @RpcParameter(name = "index")
                    Integer index,
            @RpcParameter(name = "filterIndex")
                    Integer filterIndex)
            throws Exception {
        if (mScanFilterList.get(index) != null) {
            if (mScanFilterList.get(index).get(filterIndex) != null) {
                return mScanFilterList.get(index).get(filterIndex).getIrk();
            } else {
                throw new Exception("Invalid filterIndex input:" + filterIndex);
            }
        } else {
            throw new Exception("Invalid index input:" + index);
        }
    }

    /**
     * Get ScanFilter's device name
     *
     * @param index the ScanFilter object to use
     * @return the ScanFilter's device name
     * @throws Exception
     */
    @Rpc(description = "Get ScanFilter's device name")
    public String bleGetScanFilterDeviceName(
            @RpcParameter(name = "index")
            Integer index,
            @RpcParameter(name = "filterIndex")
            Integer filterIndex)
            throws Exception {
        if (mScanFilterList.get(index) != null) {
            if (mScanFilterList.get(index).get(filterIndex) != null) {
                return mScanFilterList.get(index).get(
                        filterIndex).getDeviceName();
            } else {
                throw new Exception("Invalid filterIndex input:"
                        + Integer.toString(filterIndex));
            }
        } else {
            throw new Exception("Invalid index input:"
                    + Integer.toString(index));
        }
    }

    /**
     * Get ScanFilter's manufacturer data
     *
     * @param index the ScanFilter object to use
     * @return the ScanFilter's manufacturer data
     * @throws Exception
     */
    @Rpc(description = "Get ScanFilter's manufacturer data")
    public byte[] bleGetScanFilterManufacturerData(
            @RpcParameter(name = "index")
            Integer index,
            @RpcParameter(name = "filterIndex")
            Integer filterIndex)
            throws Exception {
        if (mScanFilterList.get(index) != null) {
            if (mScanFilterList.get(index).get(filterIndex) != null) {
                return mScanFilterList.get(index).get(
                        filterIndex).getManufacturerData();
            } else {
                throw new Exception("Invalid filterIndex input:"
                        + Integer.toString(filterIndex));
            }
        } else {
            throw new Exception("Invalid index input:"
                    + Integer.toString(index));
        }
    }

    /**
     * Get ScanFilter's manufacturer data mask
     *
     * @param index the ScanFilter object to use
     * @return the ScanFilter's manufacturer data mask
     * @throws Exception
     */
    @Rpc(description = "Get ScanFilter's manufacturer data mask")
    public byte[] bleGetScanFilterManufacturerDataMask(
            @RpcParameter(name = "index")
            Integer index,
            @RpcParameter(name = "filterIndex")
            Integer filterIndex)
            throws Exception {
        if (mScanFilterList.get(index) != null) {
            if (mScanFilterList.get(index).get(filterIndex) != null) {
                return mScanFilterList.get(index).get(
                        filterIndex).getManufacturerDataMask();
            } else {
                throw new Exception("Invalid filterIndex input:"
                        + Integer.toString(filterIndex));
            }
        } else {
            throw new Exception("Invalid index input:"
                    + Integer.toString(index));
        }
    }

    /**
     * Get ScanFilter's service data
     *
     * @param index the ScanFilter object to use
     * @return the ScanFilter's service data
     * @throws Exception
     */
    @Rpc(description = "Get ScanFilter's service data")
    public byte[] bleGetScanFilterServiceData(
            @RpcParameter(name = "index")
            Integer index,
            @RpcParameter(name = "filterIndex")
            Integer filterIndex)
            throws Exception {
        if (mScanFilterList.get(index) != null) {
            if (mScanFilterList.get(index).get(filterIndex) != null) {
                return mScanFilterList.get(index).get(
                        filterIndex).getServiceData();
            } else {
                throw new Exception("Invalid filterIndex input:"
                        + Integer.toString(filterIndex));
            }
        } else {
            throw new Exception("Invalid index input:"
                    + Integer.toString(index));
        }
    }

    /**
     * Get ScanFilter's service data mask
     *
     * @param index the ScanFilter object to use
     * @return the ScanFilter's service data mask
     * @throws Exception
     */
    @Rpc(description = "Get ScanFilter's service data mask")
    public byte[] bleGetScanFilterServiceDataMask(
            @RpcParameter(name = "index")
            Integer index,
            @RpcParameter(name = "filterIndex")
            Integer filterIndex)
            throws Exception {
        if (mScanFilterList.get(index) != null) {
            if (mScanFilterList.get(index).get(filterIndex) != null) {
                return mScanFilterList.get(index).get(
                        filterIndex).getServiceDataMask();
            } else {
                throw new Exception("Invalid filterIndex input:"
                        + Integer.toString(filterIndex));
            }
        } else {
            throw new Exception("Invalid index input:"
                    + Integer.toString(index));
        }
    }

    /**
     * Get ScanFilter's service uuid
     *
     * @param index the ScanFilter object to use
     * @return the ScanFilter's service uuid
     * @throws Exception
     */
    @Rpc(description = "Get ScanFilter's service uuid")
    public String bleGetScanFilterServiceUuid(
            @RpcParameter(name = "index")
            Integer index,
            @RpcParameter(name = "filterIndex")
            Integer filterIndex)
            throws Exception {
        if (mScanFilterList.get(index) != null) {
            if (mScanFilterList.get(index).get(filterIndex) != null) {
                if (mScanFilterList.get(index).get(
                        filterIndex).getServiceUuid() != null) {
                    return mScanFilterList.get(index).get(
                            filterIndex).getServiceUuid().toString();
                } else {
                    throw new Exception("No Service Uuid set for filter:"
                            + Integer.toString(filterIndex));
                }
            } else {
                throw new Exception("Invalid filterIndex input:"
                        + Integer.toString(filterIndex));
            }
        } else {
            throw new Exception("Invalid index input:"
                    + Integer.toString(index));
        }
    }

    /**
     * Get ScanFilter's service uuid mask
     *
     * @param index the ScanFilter object to use
     * @return the ScanFilter's service uuid mask
     * @throws Exception
     */
    @Rpc(description = "Get ScanFilter's service uuid mask")
    public String bleGetScanFilterServiceUuidMask(
            @RpcParameter(name = "index")
            Integer index,
            @RpcParameter(name = "filterIndex")
            Integer filterIndex)
            throws Exception {
        if (mScanFilterList.get(index) != null) {
            if (mScanFilterList.get(index).get(filterIndex) != null) {
                if (mScanFilterList.get(index).get(
                        filterIndex).getServiceUuidMask() != null) {
                    return mScanFilterList.get(
                            index).get(filterIndex).getServiceUuidMask()
                            .toString();
                } else {
                    throw new Exception("No Service Uuid Mask set for filter:"
                            + Integer.toString(filterIndex));
                }
            } else {
                throw new Exception("Invalid filterIndex input:"
                        + Integer.toString(filterIndex));
            }
        } else {
            throw new Exception("Invalid index input:"
                    + Integer.toString(index));
        }
    }

    /**
     * Add filter "macAddress" to existing ScanFilter
     *
     * @param macAddress the macAddress to filter against
     * @throws Exception
     */
    @Rpc(description = "Add filter \"macAddress\" to existing ScanFilter")
    public void bleSetScanFilterDeviceAddress(
            @RpcParameter(name = "macAddress")
            String macAddress
            ) {
            mScanFilterBuilder.setDeviceAddress(macAddress);
    }

    /**
     * Add filter "macAddress", and "addressType" to existing ScanFilter
     *
     * @param macAddress the macAddress to filter against
     * @param addressType the type of macAddress to filter against
     * @throws Exception
     */
    @Rpc(description = "Add filter \"macAddress\" and \"addressType\" to existing ScanFilter")
    public void bleSetScanFilterDeviceAddressAndType(
            @RpcParameter(name = "macAddress") String macAddress,
            @RpcParameter(name = "addressType") Integer addressType
    ) {
        mScanFilterBuilder.setDeviceAddress(macAddress, addressType);
    }

    /**
     * Add filter "macAddress", "addressType", and "irk" to existing ScanFilter
     *
     * @param macAddress the macAddress to filter against
     * @param addressType the type of macAddress to filter against
     * @param irk IRK for address resolution
     * @throws Exception
     */
    @Rpc(description =
            "Add filter \"macAddress\", \"addressType\", and \"irk\" to existing ScanFilter")
    public void bleSetScanFilterDeviceAddressTypeAndIrk(
            @RpcParameter(name = "macAddress") String macAddress,
            @RpcParameter(name = "addressType") Integer addressType,
            @RpcParameter(name = "irk") byte[] irk
    ) {
        mScanFilterBuilder.setDeviceAddress(macAddress, addressType, irk);
    }

    /**
     * Add filter "manufacturereDataId and/or manufacturerData" to existing
     * ScanFilter
     * @param manufacturerDataId the manufacturer data id to filter against
     * @param manufacturerDataMask the manufacturere data mask to filter against
     * @throws Exception
     */
    @Rpc(description = "Add filter \"manufacturereDataId and/or manufacturerData\" to existing ScanFilter")
    public void bleSetScanFilterManufacturerData(
            @RpcParameter(name = "manufacturerDataId")
            Integer manufacturerDataId,
            @RpcParameter(name = "manufacturerData")
            byte[] manufacturerData,
            @RpcParameter(name = "manufacturerDataMask")
            @RpcOptional
            byte[] manufacturerDataMask
            ){
        if (manufacturerDataMask != null) {
            mScanFilterBuilder.setManufacturerData(manufacturerDataId,
                    manufacturerData, manufacturerDataMask);
        } else {
            mScanFilterBuilder.setManufacturerData(manufacturerDataId,
                    manufacturerData);
        }
    }

    /**
     * Add filter "serviceData and serviceDataMask" to existing ScanFilter
     *
     * @param serviceData the service data to filter against
     * @param serviceDataMask the servie data mask to filter against
     * @throws Exception
     */
    @Rpc(description = "Add filter \"serviceData and serviceDataMask\" to existing ScanFilter ")
    public void bleSetScanFilterServiceData(
            @RpcParameter(name = "serviceUuid") String serviceUuid,
            @RpcParameter(name = "serviceData") byte[] serviceData,
            @RpcParameter(name = "serviceDataMask")
            @RpcOptional byte[] serviceDataMask
            ) {
        if (serviceDataMask != null) {
            mScanFilterBuilder
                    .setServiceData(
                            ParcelUuid.fromString(serviceUuid),
                            serviceData, serviceDataMask);
        } else {
            mScanFilterBuilder.setServiceData(ParcelUuid.fromString(serviceUuid),
                    serviceData);
        }
    }

    /**
     * Add filter "serviceUuid and/or serviceMask" to existing ScanFilter
     *
     * @param serviceUuid the service uuid to filter against
     * @param serviceMask the service mask to filter against
     * @throws Exception
     */
    @Rpc(description = "Add filter \"serviceUuid and/or serviceMask\" to existing ScanFilter")
    public void bleSetScanFilterServiceUuid(
            @RpcParameter(name = "serviceUuid")
            String serviceUuid,
            @RpcParameter(name = "serviceMask")
            @RpcOptional
            String serviceMask
            ) {
        if (serviceMask != null) {
            mScanFilterBuilder
                    .setServiceUuid(ParcelUuid.fromString(serviceUuid),
                            ParcelUuid.fromString(serviceMask));
        } else {
            mScanFilterBuilder.setServiceUuid(ParcelUuid.fromString(serviceUuid));
        }
    }

    /**
     * Add filter "device name" to existing ScanFilter
     *
     * @param name the device name to filter against
     * @throws Exception
     */
    @Rpc(description = "Sets the scan filter's device name")
    public void bleSetScanFilterDeviceName(
            @RpcParameter(name = "name")
            String name
            ) {
            mScanFilterBuilder.setDeviceName(name);
    }

    @Rpc(description = "Set the scan setting's match mode")
    public void bleSetScanSettingsMatchMode(
            @RpcParameter(name = "mode") Integer mode) {
        mScanSettingsBuilder.setMatchMode(mode);
    }

    @Rpc(description = "Get the scan setting's match mode")
    public int bleGetScanSettingsMatchMode(
            @RpcParameter(name = "scanSettingsIndex") Integer scanSettingsIndex
            ) {
        return mScanSettingsList.get(scanSettingsIndex).getMatchMode();
    }

    @Rpc(description = "Set the scan setting's number of matches")
    public void bleSetScanSettingsNumOfMatches(
            @RpcParameter(name = "matches") Integer matches) {
        mScanSettingsBuilder.setNumOfMatches(matches);
    }

    @Rpc(description = "Get the scan setting's number of matches")
    public int bleGetScanSettingsNumberOfMatches(
            @RpcParameter(name = "scanSettingsIndex")
            Integer scanSettingsIndex) {
        return  mScanSettingsList.get(scanSettingsIndex).getNumOfMatches();
    }

    private class myScanCallback extends ScanCallback {
        public Integer index;
        String mEventType;
        private final Bundle mResults;

        public myScanCallback(Integer idx) {
            index = idx;
            mEventType = "BleScan";
            mResults = new Bundle();
        }

        @Override
        public void onScanFailed(int errorCode) {
            String errorString = "UNKNOWN_ERROR_CODE";
            if (errorCode == ScanCallback.SCAN_FAILED_ALREADY_STARTED) {
                errorString = "SCAN_FAILED_ALREADY_STARTED";
            } else if (errorCode
                    == ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED) {
                errorString = "SCAN_FAILED_APPLICATION_REGISTRATION_FAILED";
            } else if (errorCode
                    == ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED) {
                errorString = "SCAN_FAILED_FEATURE_UNSUPPORTED";
            } else if (errorCode == ScanCallback.SCAN_FAILED_INTERNAL_ERROR) {
                errorString = "SCAN_FAILED_INTERNAL_ERROR";
            }
            Log.d("bluetooth_le_scan change onScanFailed "
                    + mEventType + " " + index + " error "
                    + errorString);
            mResults.putInt("ID", index);
            mResults.putString("Type", "onScanFailed");
            mResults.putInt("ErrorCode", errorCode);
            mResults.putString("Error", errorString);
            mEventFacade.postEvent(mEventType + index + "onScanFailed",
                    mResults.clone());
            mResults.clear();
        }

        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            Log.d("bluetooth_le_scan change onUpdate "
                    + mEventType + " " + index);
            mResults.putInt("ID", index);
            mResults.putInt("CallbackType", callbackType);
            mResults.putString("Type", "onScanResult");
            mResults.putParcelable("Result", result);
            mEventFacade.postEvent(
                    mEventType + index + "onScanResults", mResults.clone());
            mResults.clear();
        }

        @Override
        public void onBatchScanResults(List<ScanResult> results) {
            Log.d("reportResult " + mEventType + " " + index);
            mResults.putLong("Timestamp", System.currentTimeMillis() / 1000);
            mResults.putInt("ID", index);
            mResults.putString("Type", "onBatchScanResults");
            mResults.putParcelableList("Results", results);
            mEventFacade.postEvent(mEventType
                    + index + "onBatchScanResult", mResults.clone());
            mResults.clear();
        }
    }

    private class myLeScanCallback implements LeScanCallback {
        public Integer index;
        String mEventType;
        private final Bundle mResults;

        public myLeScanCallback(Integer idx) {
            index = idx;
            mEventType = "ClassicBleScan";
            mResults = new Bundle();
        }

        @Override
        public void onLeScan(
                BluetoothDevice device, int rssi, byte[] scanRecord) {
            Log.d("bluetooth_classic_le_scan " + mEventType + " " + index);
            mResults.putParcelable("Device", device);
            mResults.putInt("Rssi", rssi);
            mResults.putByteArray("ScanRecord", scanRecord);
            mResults.putString("Type", "onLeScan");
            mEventFacade.postEvent(mEventType
                    + index + "onLeScan", mResults.clone());
            mResults.clear();
        }
    }

    @Override
    public void shutdown() {
        if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) {
            for (myScanCallback mScanCallback : mScanCallbackList.values()) {
                if (mScanCallback != null) {
                    try {
                        mBluetoothAdapter.getBluetoothLeScanner()
                                .stopScan(mScanCallback);
                    } catch (NullPointerException e) {
                        Log.e("Failed to stop ble scan callback.", e);
                    }
                }
            }
            for (myLeScanCallback mLeScanCallback : mLeScanCallbackList.values()) {
                if (mLeScanCallback != null) {
                    try {
                        mBluetoothAdapter.stopLeScan(mLeScanCallback);
                    } catch (NullPointerException e) {
                        Log.e("Failed to stop classic ble scan callback.", e);
                    }
                }
            }
        }
        mScanCallbackList.clear();
        mScanFilterList.clear();
        mScanSettingsList.clear();
        mLeScanCallbackList.clear();
    }
}
