/*
 * 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.le.AdvertiseCallback;
import android.bluetooth.le.AdvertiseData;
import android.bluetooth.le.AdvertiseData.Builder;
import android.bluetooth.le.AdvertiseSettings;
import android.bluetooth.le.BluetoothLeAdvertiser;
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.RpcParameter;

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

/**
 * BluetoothLe Advertise functions.
 */

public class BluetoothLeAdvertiseFacade extends RpcReceiver {

    private final EventFacade mEventFacade;
    private BluetoothAdapter mBluetoothAdapter;
    private static int BleAdvertiseCallbackCount;
    private static int BleAdvertiseSettingsCount;
    private static int BleAdvertiseDataCount;
    private final HashMap<Integer, MyAdvertiseCallback> mAdvertiseCallbackList;
    private final BluetoothLeAdvertiser mAdvertise;
    private final Service mService;
    private Builder mAdvertiseDataBuilder;
    private android.bluetooth.le.AdvertiseSettings.Builder mAdvertiseSettingsBuilder;
    private final HashMap<Integer, AdvertiseData> mAdvertiseDataList;
    private final HashMap<Integer, AdvertiseSettings> mAdvertiseSettingsList;

    public BluetoothLeAdvertiseFacade(FacadeManager manager) {
        super(manager);
        mService = manager.getService();
        mBluetoothAdapter = MainThread.run(mService,
                new Callable<BluetoothAdapter>() {
                    @Override
                    public BluetoothAdapter call() throws Exception {
                        return BluetoothAdapter.getDefaultAdapter();
                    }
                });
        mEventFacade = manager.getReceiver(EventFacade.class);
        mAdvertiseCallbackList = new HashMap<Integer, MyAdvertiseCallback>();
        mAdvertise = mBluetoothAdapter.getBluetoothLeAdvertiser();
        mAdvertiseDataList = new HashMap<Integer, AdvertiseData>();
        mAdvertiseSettingsList = new HashMap<Integer, AdvertiseSettings>();
        mAdvertiseDataBuilder = new Builder();
        mAdvertiseSettingsBuilder =
                new android.bluetooth.le.AdvertiseSettings.Builder();
    }

    /**
     * Constructs a MyAdvertiseCallback obj and returns its index
     *
     * @return MyAdvertiseCallback.index
     */
    @Rpc(description = "Generate a new myAdvertisement Object")
    public Integer bleGenBleAdvertiseCallback() {
        BleAdvertiseCallbackCount += 1;
        int index = BleAdvertiseCallbackCount;
        MyAdvertiseCallback mCallback = new MyAdvertiseCallback(index);
        mAdvertiseCallbackList.put(mCallback.index,
                mCallback);
        return mCallback.index;
    }

    /**
     * Constructs a AdvertiseData obj and returns its index
     *
     * @return index
     */
    @Rpc(description =
            "Constructs a new Builder obj for AdvertiseData and returns its index")
    public Integer bleBuildAdvertiseData() {
        BleAdvertiseDataCount += 1;
        int index = BleAdvertiseDataCount;
        mAdvertiseDataList.put(index,
                mAdvertiseDataBuilder.build());
        mAdvertiseDataBuilder = new Builder();
        return index;
    }

    /**
     * Constructs a Advertise Settings obj and returns its index
     *
     * @return index
     */
    @Rpc(description =
            "Constructs a new Builder obj for AdvertiseData and returns its index")
    public Integer bleBuildAdvertiseSettings() {
        BleAdvertiseSettingsCount += 1;
        int index = BleAdvertiseSettingsCount;
        mAdvertiseSettingsList.put(index,
                mAdvertiseSettingsBuilder.build());
        mAdvertiseSettingsBuilder =
                new android.bluetooth.le.AdvertiseSettings.Builder();
        return index;
    }

    /**
     * Stops a ble advertisement
     *
     * @param index the id of the advertisement to stop advertising on
     * @throws Exception
     */
    @Rpc(description = "Stops an ongoing ble advertisement")
    public void bleStopBleAdvertising(
            @RpcParameter(name = "index")
            Integer index) throws Exception {
        if (mAdvertiseCallbackList.get(index) != null) {
            Log.d("bluetooth_le mAdvertise " + index);
            mAdvertise.stopAdvertising(mAdvertiseCallbackList
                    .get(index));
        } else {
            throw new Exception("Invalid index input:"
                    + Integer.toString(index));
        }
    }

    /**
     * Starts ble advertising
     *
     * @param callbackIndex The advertisementCallback index
     * @param dataIndex the AdvertiseData index
     * @param settingsIndex the advertisementsettings index
     * @throws Exception
     */
    @Rpc(description = "Starts ble advertisement")
    public void bleStartBleAdvertising(
            @RpcParameter(name = "callbackIndex")
            Integer callbackIndex,
            @RpcParameter(name = "dataIndex")
            Integer dataIndex,
            @RpcParameter(name = "settingsIndex")
            Integer settingsIndex
            ) throws Exception {
        AdvertiseData mData = new AdvertiseData.Builder().build();
        AdvertiseSettings mSettings = new AdvertiseSettings.Builder().build();
        if (mAdvertiseDataList.get(dataIndex) != null) {
            mData = mAdvertiseDataList.get(dataIndex);
        } else {
            throw new Exception("Invalid dataIndex input:"
                    + Integer.toString(dataIndex));
        }
        if (mAdvertiseSettingsList.get(settingsIndex) != null) {
            mSettings = mAdvertiseSettingsList.get(settingsIndex);
        } else {
            throw new Exception("Invalid settingsIndex input:"
                    + Integer.toString(settingsIndex));
        }
        if (mAdvertiseCallbackList.get(callbackIndex) != null) {
            Log.d("bluetooth_le starting a background advertisement on callback index: "
                    + Integer.toString(callbackIndex));
            mAdvertise.startAdvertising(
                    mSettings, mData, mAdvertiseCallbackList.get(callbackIndex));
        } else {
            throw new Exception("Invalid callbackIndex input"
                    + Integer.toString(callbackIndex));
        }
    }

    /**
     * Starts ble advertising with a scanResponse. ScanResponses are created in
     *        the same way
     * AdvertiseData is created since they share the same object type.
     *
     * @param callbackIndex The advertisementCallback index
     * @param dataIndex the AdvertiseData index
     * @param settingsIndex the advertisementsettings index
     * @param scanResponseIndex the scanResponse index
     * @throws Exception
     */
    @Rpc(description = "Starts ble advertisement")
    public void bleStartBleAdvertisingWithScanResponse(
            @RpcParameter(name = "callbackIndex")
            Integer callbackIndex,
            @RpcParameter(name = "dataIndex")
            Integer dataIndex,
            @RpcParameter(name = "settingsIndex")
            Integer settingsIndex,
            @RpcParameter(name = "scanResponseIndex")
            Integer scanResponseIndex
            ) throws Exception {
        AdvertiseData mData = new AdvertiseData.Builder().build();
        AdvertiseSettings mSettings = new AdvertiseSettings.Builder().build();
        AdvertiseData mScanResponse = new AdvertiseData.Builder().build();

        if (mAdvertiseDataList.get(dataIndex) != null) {
            mData = mAdvertiseDataList.get(dataIndex);
        } else {
            throw new Exception("Invalid dataIndex input:"
                    + Integer.toString(dataIndex));
        }
        if (mAdvertiseSettingsList.get(settingsIndex) != null) {
            mSettings = mAdvertiseSettingsList.get(settingsIndex);
        } else {
            throw new Exception("Invalid settingsIndex input:"
                    + Integer.toString(settingsIndex));
        }
        if (mAdvertiseDataList.get(scanResponseIndex) != null) {
            mScanResponse = mAdvertiseDataList.get(scanResponseIndex);
        } else {
            throw new Exception("Invalid scanResponseIndex input:"
                    + Integer.toString(settingsIndex));
        }
        if (mAdvertiseCallbackList.get(callbackIndex) != null) {
            Log.d("bluetooth_le starting a background advertise on callback index: "
                    + Integer.toString(callbackIndex));
            mAdvertise
                    .startAdvertising(mSettings, mData, mScanResponse,
                            mAdvertiseCallbackList.get(callbackIndex));
        } else {
            throw new Exception("Invalid callbackIndex input"
                    + Integer.toString(callbackIndex));
        }
    }

    /**
     * Get ble advertisement settings mode
     *
     * @param index the advertise settings object to use
     * @return the mode of the advertise settings object
     * @throws Exception
     */
    @Rpc(description = "Get ble advertisement settings mode")
    public int bleGetAdvertiseSettingsMode(
            @RpcParameter(name = "index")
            Integer index) throws Exception {
        if (mAdvertiseSettingsList.get(index) != null) {
            AdvertiseSettings mSettings = mAdvertiseSettingsList.get(index);
            return mSettings.getMode();
        } else {
            throw new Exception("Invalid index input:"
                    + Integer.toString(index));
        }
    }

    /**
     * Get ble advertisement settings tx power level
     *
     * @param index the advertise settings object to use
     * @return the tx power level of the advertise settings object
     * @throws Exception
     */
    @Rpc(description = "Get ble advertisement settings tx power level")
    public int bleGetAdvertiseSettingsTxPowerLevel(
            @RpcParameter(name = "index")
            Integer index) throws Exception {
        if (mAdvertiseSettingsList.get(index) != null) {
            AdvertiseSettings mSettings = mAdvertiseSettingsList.get(index);
            return mSettings.getTxPowerLevel();
        } else {
            throw new Exception("Invalid index input:" + Integer.toString(index));
        }
    }

    /**
     * Get ble advertisement settings isConnectable value
     *
     * @param index the advertise settings object to use
     * @return the boolean value whether the advertisement will indicate
     * connectable.
     * @throws Exception
     */
    @Rpc(description = "Get ble advertisement settings isConnectable value")
    public boolean bleGetAdvertiseSettingsIsConnectable(
            @RpcParameter(name = "index")
            Integer index) throws Exception {
        if (mAdvertiseSettingsList.get(index) != null) {
            AdvertiseSettings mSettings = mAdvertiseSettingsList.get(index);
            return mSettings.isConnectable();
        } else {
            throw new Exception("Invalid index input:" + Integer.toString(index));
        }
    }

    /**
     * Get ble advertisement data include tx power level
     *
     * @param index the advertise data object to use
     * @return True if include tx power level, false otherwise
     * @throws Exception
     */
    @Rpc(description = "Get ble advertisement data include tx power level")
    public Boolean bleGetAdvertiseDataIncludeTxPowerLevel(
            @RpcParameter(name = "index")
            Integer index) throws Exception {
        if (mAdvertiseDataList.get(index) != null) {
            AdvertiseData mData = mAdvertiseDataList.get(index);
            return mData.getIncludeTxPowerLevel();
        } else {
            throw new Exception("Invalid index input:"
                    + Integer.toString(index));
        }
    }

    /**
     * Get ble advertisement data manufacturer specific data
     *
     * @param index the advertise data object to use
     * @param manufacturerId the id that corresponds to the manufacturer specific data.
     * @return the corresponding manufacturer specific data to the manufacturer id.
     * @throws Exception
     */
    @Rpc(description = "Get ble advertisement data manufacturer specific data")
    public byte[] bleGetAdvertiseDataManufacturerSpecificData(
            @RpcParameter(name = "index")
            Integer index,
            @RpcParameter(name = "manufacturerId")
            Integer manufacturerId) throws Exception {
        if (mAdvertiseDataList.get(index) != null) {
            AdvertiseData mData = mAdvertiseDataList.get(index);
            if (mData.getManufacturerSpecificData() != null) {
                return mData.getManufacturerSpecificData().get(manufacturerId);
            } else {
                throw new Exception("Invalid manufacturerId input:"
                        + Integer.toString(manufacturerId));
            }
        } else {
            throw new Exception("Invalid index input:"
                    + Integer.toString(index));

        }
    }

    /**
     * Get ble advertisement data include device name
     *
     * @param index the advertise data object to use
     * @return the advertisement data's include device name
     * @throws Exception
     */
    @Rpc(description = "Get ble advertisement include device name")
    public Boolean bleGetAdvertiseDataIncludeDeviceName(
            @RpcParameter(name = "index")
            Integer index) throws Exception {
        if (mAdvertiseDataList.get(index) != null) {
            AdvertiseData mData = mAdvertiseDataList.get(index);
            return mData.getIncludeDeviceName();
        } else {
            throw new Exception("Invalid index input:"
                    + Integer.toString(index));
        }
    }

    /**
     * Get ble advertisement Service Data
     *
     * @param index the advertise data object to use
     * @param serviceUuid the uuid corresponding to the service data.
     * @return the advertisement data's service data
     * @throws Exception
     */
    @Rpc(description = "Get ble advertisement Service Data")
    public byte[] bleGetAdvertiseDataServiceData(
            @RpcParameter(name = "index")
            Integer index,
            @RpcParameter(name = "serviceUuid")
            String serviceUuid) throws Exception {
        ParcelUuid uuidKey = ParcelUuid.fromString(serviceUuid);
        if (mAdvertiseDataList.get(index) != null) {
            AdvertiseData mData = mAdvertiseDataList.get(index);
            if (mData.getServiceData().containsKey(uuidKey)) {
                return mData.getServiceData().get(uuidKey);
            } else {
                throw new Exception("Invalid serviceUuid input:" + serviceUuid);
            }
        } else {
            throw new Exception("Invalid index input:"
                    + Integer.toString(index));
        }
    }

    /**
     * Get ble advertisement Service Uuids
     *
     * @param index the advertise data object to use
     * @return the advertisement data's Service Uuids
     * @throws Exception
     */
    @Rpc(description = "Get ble advertisement Service Uuids")
    public List<ParcelUuid> bleGetAdvertiseDataServiceUuids(
            @RpcParameter(name = "index")
            Integer index) throws Exception {
        if (mAdvertiseDataList.get(index) != null) {
            AdvertiseData mData = mAdvertiseDataList.get(index);
            return mData.getServiceUuids();
        } else {
            throw new Exception("Invalid index input:"
                    + Integer.toString(index));
        }
    }

    /**
     * Set ble advertisement data service uuids
     *
     * @param uuidList
     * @throws Exception
     */
    @Rpc(description = "Set ble advertisement data service uuids")
    public void bleSetAdvertiseDataSetServiceUuids(
            @RpcParameter(name = "uuidList")
            String[] uuidList
            ) {
        for (String uuid : uuidList) {
            mAdvertiseDataBuilder.addServiceUuid(ParcelUuid.fromString(uuid));
        }
    }

    /**
     * Set ble advertise data service uuids
     *
     * @param serviceDataUuid
     * @param serviceData
     * @throws Exception
     */
    @Rpc(description = "Set ble advertise data service uuids")
    public void bleAddAdvertiseDataServiceData(
            @RpcParameter(name = "serviceDataUuid")
            String serviceDataUuid,
            @RpcParameter(name = "serviceData")
            byte[] serviceData
            ) {
        mAdvertiseDataBuilder.addServiceData(
                ParcelUuid.fromString(serviceDataUuid),
                serviceData);
    }

    /**
     * Set ble advertise data manufacturer id
     *
     * @param manufacturerId the manufacturer id to set
     * @param manufacturerSpecificData the manufacturer specific data to set
     * @throws Exception
     */
    @Rpc(description = "Set ble advertise data manufacturerId")
    public void bleAddAdvertiseDataManufacturerId(
            @RpcParameter(name = "manufacturerId")
            Integer manufacturerId,
            @RpcParameter(name = "manufacturerSpecificData")
            byte[] manufacturerSpecificData
            ) {
        mAdvertiseDataBuilder.addManufacturerData(manufacturerId,
                manufacturerSpecificData);
    }

    /**
     * Set ble advertise settings advertise mode
     *
     * @param advertiseMode
     * @throws Exception
     */
    @Rpc(description = "Set ble advertise settings advertise mode")
    public void bleSetAdvertiseSettingsAdvertiseMode(
            @RpcParameter(name = "advertiseMode")
            Integer advertiseMode
            ) {
        mAdvertiseSettingsBuilder.setAdvertiseMode(advertiseMode);
    }

    /**
     * Set ble advertise settings tx power level
     *
     * @param txPowerLevel the tx power level to set
     * @throws Exception
     */
    @Rpc(description = "Set ble advertise settings tx power level")
    public void bleSetAdvertiseSettingsTxPowerLevel(
            @RpcParameter(name = "txPowerLevel")
            Integer txPowerLevel
            ) {
        mAdvertiseSettingsBuilder.setTxPowerLevel(txPowerLevel);
    }

    /**
     * Set ble advertise settings the isConnectable value
     *
     * @param type the isConnectable value
     * @throws Exception
     */
    @Rpc(description = "Set ble advertise settings isConnectable value")
    public void bleSetAdvertiseSettingsIsConnectable(
            @RpcParameter(name = "value")
            Boolean value
            ) {
        mAdvertiseSettingsBuilder.setConnectable(value);
    }

    /**
     * Set ble advertisement data include tx power level
     *
     * @param includeTxPowerLevel boolean whether to include the tx
     *         power level or not in the advertisement
     */
    @Rpc(description = "Set ble advertisement data include tx power level")
    public void bleSetAdvertiseDataIncludeTxPowerLevel(
            @RpcParameter(name = "includeTxPowerLevel")
            Boolean includeTxPowerLevel
            ) {
        mAdvertiseDataBuilder.setIncludeTxPowerLevel(includeTxPowerLevel);
    }

    /**
     * Set ble advertisement settings set timeout
     *
     * @param timeoutSeconds Limit advertising to a given amount of time.
     */
    @Rpc(description = "Set ble advertisement data include tx power level")
    public void bleSetAdvertiseSettingsTimeout(
            @RpcParameter(name = "timeoutSeconds")
            Integer timeoutSeconds
            ) {
        mAdvertiseSettingsBuilder.setTimeout(timeoutSeconds);
    }

    /**
     * Set ble advertisement data include device name
     *
     * @param includeDeviceName boolean whether to include device name or
     *        not in the advertisement
     */
    @Rpc(description = "Set ble advertisement data include device name")
    public void bleSetAdvertiseDataIncludeDeviceName(
            @RpcParameter(name = "includeDeviceName")
            Boolean includeDeviceName
            ) {
        mAdvertiseDataBuilder.setIncludeDeviceName(includeDeviceName);
    }

    private class MyAdvertiseCallback extends AdvertiseCallback {
        public Integer index;
        private final Bundle mResults;
        String mEventType;

        public MyAdvertiseCallback(int idx) {
            index = idx;
            mEventType = "BleAdvertise";
            mResults = new Bundle();
        }

        @Override
        public void onStartSuccess(AdvertiseSettings settingsInEffect) {
            Log.d("bluetooth_le_advertisement onSuccess " + mEventType + " "
                    + index);
            mResults.putString("Type", "onSuccess");
            mResults.putParcelable("SettingsInEffect", settingsInEffect);
            mEventFacade.postEvent(mEventType + index
                    + "onSuccess", mResults.clone());
            mResults.clear();
        }

        @Override
        public void onStartFailure(int errorCode) {
            String errorString = "UNKNOWN_ERROR_CODE";
            if (errorCode
                    == AdvertiseCallback.ADVERTISE_FAILED_ALREADY_STARTED) {
                errorString = "ADVERTISE_FAILED_ALREADY_STARTED";
            } else if (errorCode
                    == AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE) {
                errorString = "ADVERTISE_FAILED_DATA_TOO_LARGE";
            } else if (errorCode
                    == AdvertiseCallback.ADVERTISE_FAILED_FEATURE_UNSUPPORTED) {
                errorString = "ADVERTISE_FAILED_FEATURE_UNSUPPORTED";
            } else if (errorCode
                    == AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR) {
                errorString = "ADVERTISE_FAILED_INTERNAL_ERROR";
            } else if (errorCode
                    == AdvertiseCallback.ADVERTISE_FAILED_TOO_MANY_ADVERTISERS) {
                errorString = "ADVERTISE_FAILED_TOO_MANY_ADVERTISERS";
            }
            Log.d("bluetooth_le_advertisement onFailure " + mEventType + " "
                    + index + " error " + errorString);
            mResults.putString("Type", "onFailure");
            mResults.putInt("ErrorCode", errorCode);
            mResults.putString("Error", errorString);
            mEventFacade.postEvent(mEventType + index + "onFailure",
                    mResults.clone());
            mResults.clear();
        }
    }

    /**
     * Clear all advertise settings
     *
     * @param None
     */
    @Rpc(description = "Clear all advertise settings")
    public void bleAdvertiseClearAll() {
        Log.d("bleAdvertiseClearAll: called");
        if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) {
            for (MyAdvertiseCallback mAdvertise : mAdvertiseCallbackList
                .values()) {
                if (mAdvertise != null) {
                    try{
                        mBluetoothAdapter.getBluetoothLeAdvertiser()
                            .stopAdvertising(mAdvertise);
                    } catch (NullPointerException e) {
                        Log.e("Failed to stop ble advertising.", e);
                    }
                }
            }
        }
        mAdvertiseCallbackList.clear();
        mAdvertiseSettingsList.clear();
        mAdvertiseDataList.clear();
    }

    @Override
    public void shutdown() {
        bleAdvertiseClearAll();
    }
}
