// Copyright 2016 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.impl.google.discovery.plugins.ble;

import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattServer;
import android.bluetooth.BluetoothGattServerCallback;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Context;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * A server that serves Vanadium Gatt services to remote Gatt readers.
 */
class GattServer extends BluetoothGattServerCallback {
    // L2CAP implementations shall support a minimum MTU size of 23 octets.
    // See Bluetooth specification version 4.2 section 5.1.
    private static final int DEFAULT_MTU = 23;

    private final BluetoothGattServer mBluetoothGattServer;
    private final Map<BluetoothDevice, Integer> mMtus;

    GattServer(Context context) {
        BluetoothManager manager =
                ((BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE));
        mBluetoothGattServer = manager.openGattServer(context, this);
        mMtus = new HashMap<BluetoothDevice, Integer>();
    }

    /**
     * Add a service to the Gatt server.
     */
    boolean addService(BluetoothGattService service) {
        return mBluetoothGattServer.addService(service);
    }

    /**
     * Removes a service from the Gatt server.
     */
    boolean removeService(BluetoothGattService service) {
        return mBluetoothGattServer.removeService(service);
    }

    /**
     * Closes the Gatt server removing all services.
     */
    void close() {
        mBluetoothGattServer.clearServices();
        mBluetoothGattServer.close();
    }

    @Override
    public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
        super.onConnectionStateChange(device, status, newState);

        if (status != BluetoothGatt.GATT_SUCCESS || newState != BluetoothProfile.STATE_CONNECTED) {
            mMtus.remove(device);
        }
    }

    @Override
    public void onMtuChanged(BluetoothDevice device, int mtu) {
        super.onMtuChanged(device, mtu);

        mMtus.put(device, mtu);
    }

    @Override
    public void onCharacteristicReadRequest(
            BluetoothDevice device,
            int requestId,
            int offset,
            BluetoothGattCharacteristic characteristic) {
        super.onCharacteristicReadRequest(device, requestId, offset, characteristic);

        byte[] data = characteristic.getValue();
        if (offset >= data.length) {
            data = null;
        } else {
            // MTU exchange is not allowed on a BR/EDR physical link. Send all requested data in that link.
            int deviceType = device.getType();
            if (deviceType == BluetoothDevice.DEVICE_TYPE_CLASSIC
                    || deviceType == BluetoothDevice.DEVICE_TYPE_DUAL) {
                if (offset > 0) {
                    data = Arrays.copyOfRange(data, offset, data.length);
                }
            } else {
                int mtu = DEFAULT_MTU;
                if (mMtus.containsKey(device)) {
                    mtu = mMtus.get(device);
                }
                // We can send data up to MTU - 1 bytes.
                int to = offset + mtu - 1;
                if (to > data.length) {
                    to = data.length;
                }
                if (offset > 0 || to < data.length) {
                    data = Arrays.copyOfRange(data, offset, to);
                }
            }
        }
        mBluetoothGattServer.sendResponse(
                device, requestId, BluetoothGatt.GATT_SUCCESS, offset, data);
    }
}
