/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.cts.verifier.bluetooth;

import java.util.Arrays;
import java.util.UUID;
import java.util.List;

import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.ParcelUuid;
import android.util.Log;
import android.widget.Toast;

public class BleClientService extends Service {

    public static final boolean DEBUG = true;
    public static final String TAG = "BleClientService";

    public static final int COMMAND_CONNECT = 0;
    public static final int COMMAND_DISCONNECT = 1;
    public static final int COMMAND_DISCOVER_SERVICE = 2;
    public static final int COMMAND_READ_RSSI = 3;
    public static final int COMMAND_WRITE_CHARACTERISTIC = 4;
    public static final int COMMAND_READ_CHARACTERISTIC = 5;
    public static final int COMMAND_WRITE_DESCRIPTOR = 6;
    public static final int COMMAND_READ_DESCRIPTOR = 7;
    public static final int COMMAND_SET_NOTIFICATION = 8;
    public static final int COMMAND_BEGIN_WRITE = 9;
    public static final int COMMAND_EXECUTE_WRITE = 10;
    public static final int COMMAND_ABORT_RELIABLE = 11;
    public static final int COMMAND_SCAN_START = 12;
    public static final int COMMAND_SCAN_STOP = 13;

    public static final String BLE_BLUETOOTH_CONNECTED =
            "com.android.cts.verifier.bluetooth.BLE_BLUETOOTH_CONNECTED";
    public static final String BLE_BLUETOOTH_DISCONNECTED =
            "com.android.cts.verifier.bluetooth.BLE_BLUETOOTH_DISCONNECTED";
    public static final String BLE_SERVICES_DISCOVERED =
            "com.android.cts.verifier.bluetooth.BLE_SERVICES_DISCOVERED";
    public static final String BLE_CHARACTERISTIC_READ =
            "com.android.cts.verifier.bluetooth.BLE_CHARACTERISTIC_READ";
    public static final String BLE_CHARACTERISTIC_WRITE =
            "com.android.cts.verifier.bluetooth.BLE_CHARACTERISTIC_WRITE";
    public static final String BLE_CHARACTERISTIC_CHANGED =
            "com.android.cts.verifier.bluetooth.BLE_CHARACTERISTIC_CHANGED";
    public static final String BLE_DESCRIPTOR_READ =
            "com.android.cts.verifier.bluetooth.BLE_DESCRIPTOR_READ";
    public static final String BLE_DESCRIPTOR_WRITE =
            "com.android.cts.verifier.bluetooth.BLE_DESCRIPTOR_WRITE";
    public static final String BLE_RELIABLE_WRITE_COMPLETED =
            "com.android.cts.verifier.bluetooth.BLE_RELIABLE_WRITE_COMPLETED";
    public static final String BLE_READ_REMOTE_RSSI =
            "com.android.cts.verifier.bluetooth.BLE_READ_REMOTE_RSSI";

    public static final String EXTRA_COMMAND =
            "com.android.cts.verifier.bluetooth.EXTRA_COMMAND";
    public static final String EXTRA_WRITE_VALUE =
            "com.android.cts.verifier.bluetooth.EXTRA_WRITE_VALUE";
    public static final String EXTRA_BOOL =
            "com.android.cts.verifier.bluetooth.EXTRA_BOOL";
    public static final String EXTRA_CHARACTERISTIC_VALUE =
            "com.android.cts.verifier.bluetooth.EXTRA_CHARACTERISTIC_VALUE";
    public static final String EXTRA_DESCRIPTOR_VALUE =
            "com.android.cts.verifier.bluetooth.EXTRA_DESCRIPTOR_VALUE";
    public static final String EXTRA_RSSI_VALUE =
            "com.android.cts.verifier.bluetooth.EXTRA_RSSI_VALUE";

    private static final UUID SERVICE_UUID =
            UUID.fromString("00009999-0000-1000-8000-00805f9b34fb");
    private static final UUID CHARACTERISTIC_UUID =
            UUID.fromString("00009998-0000-1000-8000-00805f9b34fb");
    private static final UUID UPDATE_CHARACTERISTIC_UUID =
            UUID.fromString("00009997-0000-1000-8000-00805f9b34fb");
    private static final UUID DESCRIPTOR_UUID =
            UUID.fromString("00009996-0000-1000-8000-00805f9b34fb");

    private BluetoothManager mBluetoothManager;
    private BluetoothAdapter mBluetoothAdapter;
    private BluetoothDevice mDevice;
    private BluetoothGatt mBluetoothGatt;
    private Handler mHandler;
    private Context mContext;
    private BluetoothLeScanner mScanner;

    @Override
    public void onCreate() {
        super.onCreate();

        mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = mBluetoothManager.getAdapter();
        mHandler = new Handler();
        mContext = this;
        mScanner = mBluetoothAdapter.getBluetoothLeScanner();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null) handleIntent(intent);
        return START_NOT_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mBluetoothGatt.disconnect();
        mBluetoothGatt.close();
        stopScan();
    }

    private void handleIntent(Intent intent) {
        int command = intent.getIntExtra(EXTRA_COMMAND, -1);
        String address = intent.getStringExtra(BluetoothDevice.EXTRA_DEVICE); // sometimes null
        String writeValue = intent.getStringExtra(EXTRA_WRITE_VALUE); // sometimes null
        boolean enable = intent.getBooleanExtra(EXTRA_BOOL, false);
        BluetoothGattService service;
        BluetoothGattCharacteristic characteristic;
        BluetoothGattDescriptor descriptor;

        switch (command) {
            case COMMAND_CONNECT:
                mDevice = mBluetoothAdapter.getRemoteDevice(address);
                mBluetoothGatt = mDevice.connectGatt(this, false, mGattCallbacks);
                break;
            case COMMAND_DISCONNECT:
                if (mBluetoothGatt != null) mBluetoothGatt.disconnect();
                break;
            case COMMAND_DISCOVER_SERVICE:
                if (mBluetoothGatt != null) mBluetoothGatt.discoverServices();
                break;
            case COMMAND_READ_RSSI:
                if (mBluetoothGatt != null) mBluetoothGatt.readRemoteRssi();
                break;
            case COMMAND_WRITE_CHARACTERISTIC:
                writeCharacteristic(writeValue);
                break;
            case COMMAND_READ_CHARACTERISTIC:
                readCharacteristic();
                break;
            case COMMAND_WRITE_DESCRIPTOR:
                writeDescriptor(writeValue);
                break;
            case COMMAND_READ_DESCRIPTOR:
                readDescriptor();
                break;
            case COMMAND_SET_NOTIFICATION:
                setNotification(enable);
                break;
            case COMMAND_BEGIN_WRITE:
                if (mBluetoothGatt != null) mBluetoothGatt.beginReliableWrite();
                break;
            case COMMAND_EXECUTE_WRITE:
                if (mBluetoothGatt != null) mBluetoothGatt.executeReliableWrite();
                break;
            case COMMAND_ABORT_RELIABLE:
                if (mBluetoothGatt != null) mBluetoothGatt.abortReliableWrite(mDevice);
                break;
            case COMMAND_SCAN_START:
                startScan();
                break;
            case COMMAND_SCAN_STOP:
                stopScan();
                break;
            default:
                showMessage("Unrecognized command: " + command);
                break;
        }
    }

    private void writeCharacteristic(String writeValue) {
        BluetoothGattCharacteristic characteristic = getCharacteristic(CHARACTERISTIC_UUID);
        if (characteristic == null) return;
        characteristic.setValue(writeValue);
        mBluetoothGatt.writeCharacteristic(characteristic);
    }

    private void readCharacteristic() {
        BluetoothGattCharacteristic characteristic = getCharacteristic(CHARACTERISTIC_UUID);
        if (characteristic != null) mBluetoothGatt.readCharacteristic(characteristic);
    }

    private void writeDescriptor(String writeValue) {
        BluetoothGattDescriptor descriptor = getDescriptor();
        if (descriptor == null) return;
        descriptor.setValue(writeValue.getBytes());
        mBluetoothGatt.writeDescriptor(descriptor);
    }

    private void readDescriptor() {
        BluetoothGattDescriptor descriptor = getDescriptor();
        if (descriptor != null) mBluetoothGatt.readDescriptor(descriptor);
    }

    private void setNotification(boolean enable) {
        BluetoothGattCharacteristic characteristic = getCharacteristic(UPDATE_CHARACTERISTIC_UUID);
        if (characteristic != null)
            mBluetoothGatt.setCharacteristicNotification(characteristic, enable);
    }

    private void notifyConnected() {
        Intent intent = new Intent(BLE_BLUETOOTH_CONNECTED);
        sendBroadcast(intent);
    }

    private void notifyDisconnected() {
        Intent intent = new Intent(BLE_BLUETOOTH_DISCONNECTED);
        sendBroadcast(intent);
    }

    private void notifyServicesDiscovered() {
        Intent intent = new Intent(BLE_SERVICES_DISCOVERED);
        sendBroadcast(intent);
    }

    private void notifyCharacteristicRead(String value) {
        Intent intent = new Intent(BLE_CHARACTERISTIC_READ);
        intent.putExtra(EXTRA_CHARACTERISTIC_VALUE, value);
        sendBroadcast(intent);
    }

    private void notifyCharacteristicWrite() {
        Intent intent = new Intent(BLE_CHARACTERISTIC_WRITE);
        sendBroadcast(intent);
    }

    private void notifyCharacteristicChanged(String value) {
        Intent intent = new Intent(BLE_CHARACTERISTIC_CHANGED);
        intent.putExtra(EXTRA_CHARACTERISTIC_VALUE, value);
        sendBroadcast(intent);
    }

    private void notifyDescriptorRead(String value) {
        Intent intent = new Intent(BLE_DESCRIPTOR_READ);
        intent.putExtra(EXTRA_DESCRIPTOR_VALUE, value);
        sendBroadcast(intent);
    }

    private void notifyDescriptorWrite() {
        Intent intent = new Intent(BLE_DESCRIPTOR_WRITE);
        sendBroadcast(intent);
    }

    private void notifyReliableWriteCompleted() {
        Intent intent = new Intent(BLE_RELIABLE_WRITE_COMPLETED);
        sendBroadcast(intent);
    }

    private void notifyReadRemoteRssi(int rssi) {
        Intent intent = new Intent(BLE_READ_REMOTE_RSSI);
        intent.putExtra(EXTRA_RSSI_VALUE, rssi);
        sendBroadcast(intent);
    }

    private BluetoothGattService getService() {
        if (mBluetoothGatt == null) return null;

        BluetoothGattService service = mBluetoothGatt.getService(SERVICE_UUID);
        if (service == null) {
            showMessage("Service not found");
            return null;
        }
        return service;
    }

    private BluetoothGattCharacteristic getCharacteristic(UUID uuid) {
        BluetoothGattService service = getService();
        if (service == null) return null;

        BluetoothGattCharacteristic characteristic = service.getCharacteristic(uuid);
        if (characteristic == null) {
            showMessage("Characteristic not found");
            return null;
        }
        return characteristic;
    }

    private BluetoothGattDescriptor getDescriptor() {
        BluetoothGattCharacteristic characteristic = getCharacteristic(CHARACTERISTIC_UUID);
        if (characteristic == null) return null;

        BluetoothGattDescriptor descriptor = characteristic.getDescriptor(DESCRIPTOR_UUID);
        if (descriptor == null) {
            showMessage("Descriptor not found");
            return null;
        }
        return descriptor;
    }

    private void showMessage(final String msg) {
        mHandler.post(new Runnable() {
            public void run() {
                Toast.makeText(BleClientService.this, msg, Toast.LENGTH_SHORT).show();
            }
        });
    }

    private final BluetoothGattCallback mGattCallbacks = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            if (DEBUG) Log.d(TAG, "onConnectionStateChange");
            if (status == BluetoothGatt.GATT_SUCCESS) {
                if (newState == BluetoothProfile.STATE_CONNECTED) notifyConnected();
                else if (status == BluetoothProfile.STATE_DISCONNECTED) {
                    notifyDisconnected();
                    showMessage("Bluetooth LE disconnected");
                }
            }
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            if ((status == BluetoothGatt.GATT_SUCCESS) &&
                (mBluetoothGatt.getService(SERVICE_UUID) != null)) {
                notifyServicesDiscovered();
            }
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt,
                                         BluetoothGattCharacteristic characteristic, int status) {
            if ((status == BluetoothGatt.GATT_SUCCESS) &&
                (characteristic.getUuid().equals(CHARACTERISTIC_UUID))) {
                notifyCharacteristicRead(characteristic.getStringValue(0));
            }
        }

        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt,
                                          BluetoothGattCharacteristic characteristic, int status) {
            if (DEBUG) Log.d(TAG, "onCharacteristicWrite: characteristic.val="
                    + characteristic.getStringValue(0) + " status=" + status);
            BluetoothGattCharacteristic mCharacteristic = getCharacteristic(CHARACTERISTIC_UUID);
            if ((status == BluetoothGatt.GATT_SUCCESS) &&
                (characteristic.getStringValue(0).equals(mCharacteristic.getStringValue(0)))) {
                notifyCharacteristicWrite();
            }
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt,
                                            BluetoothGattCharacteristic characteristic) {
            if (characteristic.getUuid().equals(UPDATE_CHARACTERISTIC_UUID))
                notifyCharacteristicChanged(characteristic.getStringValue(0));
        }

        @Override
        public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
                                     int status) {
            if ((status == BluetoothGatt.GATT_SUCCESS) &&
                (descriptor.getUuid().equals(DESCRIPTOR_UUID))) {
                notifyDescriptorRead(new String(descriptor.getValue()));
            }
        }

        @Override
        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
                                      int status) {
            if ((status == BluetoothGatt.GATT_SUCCESS) &&
                (descriptor.getUuid().equals(DESCRIPTOR_UUID))) {
                notifyDescriptorWrite();
            }
        }

        @Override
        public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) notifyReliableWriteCompleted();
        }

        @Override
        public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) notifyReadRemoteRssi(rssi);
        }
    };

    private final ScanCallback mScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            mBluetoothGatt = result.getDevice().connectGatt(mContext, false, mGattCallbacks);
        }
    };

    private void startScan() {
        if (DEBUG) Log.d(TAG, "startScan");
        List<ScanFilter> filter = Arrays.asList(new ScanFilter.Builder().setServiceUuid(
                new ParcelUuid(BleServerService.ADV_SERVICE_UUID)).build());
        ScanSettings setting = new ScanSettings.Builder()
                .setScanMode(ScanSettings.SCAN_MODE_LOW_POWER).build();
        mScanner.startScan(filter, setting, mScanCallback);
    }

    private void stopScan() {
        if (DEBUG) Log.d(TAG, "stopScan");
        mScanner.stopScan(mScanCallback);
    }
}
