// 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 {
    /**
     * A handler that will get called when all the services from a gatt service
     * are read.
     */
    public interface Callback {
        /**
         * Called with the map of service ids to their attributes.
         * @param services A map from service id to (characteristics uuid to values).
         */
        void handle(Map<UUID, Map<UUID, byte[]>> services);
    }
    // We want to ignore the GATT and GAP services, which are 1800 and 1801 respectively.
    static final String GATT_AND_GAP_PREFIX = "0000180";

    private final Callback callback;

    private final Map<UUID, Map<UUID, byte[]>> services = new HashMap<>();

    private BluetoothGatt gatt;

    private final List<BluetoothGattCharacteristic> chars = new ArrayList<>();
    private int pos;

    BluetoothGattClientCallback(Callback cb) {
        callback = cb;
    }

    @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();
    }
}
