// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package io.v.android.libs.discovery.ble;

import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.util.Log;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * BluetoothGattClientCallback is a handler for responses from a GattServer.
 */
public class BluetoothGattClientCallback extends BluetoothGattCallback {
    public interface Callback {
        void handle(Map<UUID, Map<UUID, byte[]>> services);
    }
    private Callback callback;

    private Map<UUID, Map<UUID, byte[]>> services;

    private BluetoothGatt gatt;

    private List<BluetoothGattCharacteristic> chars;
    private int pos;

    BluetoothGattClientCallback(Callback cb) {
        callback = cb;
        chars = new ArrayList<>();
        services = new Hashtable<>();
    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        for (BluetoothGattService service : gatt.getServices()) {
            // Skip the GATT AND GAP Services.
            if (service.getUuid().toString().startsWith("0000180")) {
                continue;
            }
            services.put(service.getUuid(), new HashMap<UUID, byte[]>());
            // We only keep track of the characteristics that can be read.
            for (BluetoothGattCharacteristic ch : chars) {
                if ((ch.getProperties() & BluetoothGattCharacteristic.PROPERTY_READ) != 0) {
                    chars.add(ch);
                }
            }
        }
        pos = 0;
        maybeReadNextCharacteristic();
    }

    // Reads the next characteristic if there is one.  Otherwise calls callback and
    // closes the gatt connection.
    private void maybeReadNextCharacteristic() {
        if (pos >= chars.size()) {
            gatt.disconnect();
            gatt.close();
            callback.handle(services);
            return;
        }
        BluetoothGattCharacteristic c = chars.get(pos++);
        if (!gatt.readCharacteristic(c)) {
            Log.d("vanadium", "Failed to read characteristic " + c.getUuid());
            maybeReadNextCharacteristic();
        }
    }

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        UUID serviceUUID = characteristic.getService().getUuid();
        services.get(serviceUUID).put(characteristic.getUuid(), characteristic.getValue());
        maybeReadNextCharacteristic();
    }

    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        Log.d("vanadium", "new connections state is " + newState);

        this.gatt = gatt;
        if (status != BluetoothGatt.GATT_SUCCESS || newState != BluetoothGatt.STATE_CONNECTED) {
            Log.d("vanadium", "failed to connect with status " + status + " state" + newState);
            gatt.close();
            callback.handle(null);
            return;
        }
        gatt.discoverServices();
    }
}
