// 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;

/**
 * A handler for responses from a GattServer.
 */
public class BluetoothGattClientCallback extends BluetoothGattCallback {
    // We want to ignore the GATT and GAP services, which are 1800 and 1801 respectively.
    static final String GATT_AND_GAP_PREFIX = "0000180";
    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(GATT_AND_GAP_PREFIX)) {
                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();
    }
}
