// +build linux

// Package bluetooth provides methods for interacting with attached bluetooth
// devices.
package bluetooth

import (
	"fmt"
	"math"
	"net"
	"syscall"
	"time"
	"unsafe"

	"veyron/runtimes/google/lib/proximity"
	"veyron/runtimes/google/lib/unit"
	"veyron2/vlog"
)

// // Explicitly link libbluetooth and other libraries as "go build" cannot
// // figure out these dependencies..
// #cgo LDFLAGS: -lbluetooth -ldbus-1 -lusb-1.0 -lusb -lexpat
// #include <bluetooth/bluetooth.h>
// #include <bluetooth/hci.h>
// #include <bluetooth/hci_lib.h>
// #include <stdlib.h>
// #include <unistd.h>
// #include "bt.h"
import "C"

var (
	// MaxLEAdvertisingPayloadSize denotes the maximum size for the
	// LE advertising payload.
	// See the Bluetooth 4.0 spec for more info on Bluetooth LE payload
	// structure:
	// https://www.bluetooth.org/en-us/specification/adopted-specifications
	MaxLEAdvertisingPayloadSize = int(C.kMaxLEPayloadSize)

	// MaxPort represents the highest bluetooth port that can be used
	// for establishing RFCOMM connections.
	MaxPort = int(C.kMaxPort)

	// maxDevices denotes a maximum number of local devices to scan over
	// when a particular device isn't explicitly specified (e.g.,
	// OpenFirstAvailableDevice).
	maxDevices = int(C.kMaxDevices)
)

// OpenDevice opens the Bluetooth device with a specified id, returning an
// error if the device couldn't be opened, or nil otherwise.
func OpenDevice(deviceID int) (*Device, error) {
	if deviceID < 0 {
		return nil, fmt.Errorf("negative device id, use OpenFirstAvailableDevice() instead")
	}
	var descriptor C.int
	var name *C.char
	var localMAC *C.char
	if es := C.bt_open_device(C.int(deviceID), &descriptor, &name, &localMAC); es != nil {
		defer C.free(unsafe.Pointer(es))
		return nil, fmt.Errorf("error opening device %d: %s", deviceID, C.GoString(es))
	}
	defer C.free(unsafe.Pointer(name))
	defer C.free(unsafe.Pointer(localMAC))
	mac, err := net.ParseMAC(C.GoString(localMAC))
	if err != nil {
		return nil, fmt.Errorf("illegal hardware address %q for device %d: %s", C.GoString(localMAC), deviceID, err)
	}
	return &Device{
		Name:       C.GoString(name),
		MAC:        mac,
		id:         deviceID,
		descriptor: descriptor,
	}, nil
}

// OpenFirstAvailableDevice() opens the first available bluetooth device,
// returning an error if no device could be opened, or nil otherwise.
func OpenFirstAvailableDevice() (*Device, error) {
	for devID := 0; devID < maxDevices; devID++ {
		if d, err := OpenDevice(devID); err == nil {
			return d, nil
		}
	}
	return nil, fmt.Errorf("can't find an available bluetooth device")
}

// Listen creates a new listener for RFCOMM connections on the provided
// local address, specified in the <MAC/Port> format (e.g.,
// "01:23:45:67:89:AB/1").  Port number 0 means pick the first available
// port.  Empty MAC address means pick the first available bluetooth device.
// Error is returned if a listener cannot be created.
// Note that the returned net.Listener won't use the runtime network poller
// and hence a new OS thread will be created for every outstanding connection.
func Listen(localAddr string) (net.Listener, error) {
	local, err := parseAddress(localAddr)
	if err != nil {
		return nil, fmt.Errorf("listen error: invalid local address format %s, error: %s", localAddr, err)
	}
	if local.port > MaxPort {
		return nil, fmt.Errorf("listen error: port %d too large - max: %d", local.port, MaxPort)
	}

	// Open a new local bluetooth socket.
	socket := C.socket(C.AF_BLUETOOTH, C.SOCK_STREAM, C.BTPROTO_RFCOMM)
	if socket < 0 {
		return nil, fmt.Errorf("listen error: can't open new RFCOMM socket")
	}

	// Bind to the local socket.
	var localMAC *C.char
	if !local.isAnyMAC() {
		localMAC = C.CString(local.mac.String())
	}
	defer C.free(unsafe.Pointer(localMAC))
	localPort := C.int(local.port)
	if es := C.bt_bind(socket, &localMAC, &localPort); es != nil {
		defer C.free(unsafe.Pointer(es))
		syscall.Close(int(socket))
		return nil, fmt.Errorf("listen error: %v", C.GoString(es))
	}
	// Re-parse the address as it may have changed.
	if local.mac, err = net.ParseMAC(C.GoString(localMAC)); err != nil {
		return nil, fmt.Errorf("listen error: invalid local MAC address: %s, err: %v", C.GoString(localMAC), err)
	}
	local.port = int(localPort)

	// Create a listener for incoming connections.
	const maxPendingConnections = 100
	if err = syscall.Listen(int(socket), maxPendingConnections); err != nil {
		syscall.Close(int(socket))
		return nil, fmt.Errorf("listen error: %v", err)
	}

	return &listener{
		localAddr: local,
		socket:    int(socket),
	}, nil
}

// Dial creates a new RFCOMM connection with the remote address, specified in
// the <MAC/Port> format (e.g., "01:23:45:67:89:AB/1").  It returns an error
// if the connection cannot be established.
// Note that the returned net.Conn won't use the runtime network poller and
// hence a new OS thread will be created for every outstanding connection.
func Dial(remoteAddr string) (net.Conn, error) {
	remote, err := parseAddress(remoteAddr)
	if err != nil {
		return nil, fmt.Errorf("dial error: invalid remote address format %s, error %s", remoteAddr, err)
	}
	if remote.isAnyMAC() {
		return nil, fmt.Errorf("dial error: must specify remote MAC address: %s", remoteAddr)
	}
	if remote.port > MaxPort {
		return nil, fmt.Errorf("dial error: port %d too large - max: %d", remote.port, MaxPort)
	}

	// Open a new local bluetooth socket.
	socket := C.socket(C.AF_BLUETOOTH, C.SOCK_STREAM, C.BTPROTO_RFCOMM)
	if socket < 0 {
		return nil, fmt.Errorf("dial error: can't open new RFCOMM socket")
	}

	// Bind to the local socket.
	var localMAC *C.char  // bind to first available device
	localPort := C.int(0) // bind to first available port
	if es := C.bt_bind(socket, &localMAC, &localPort); es != nil {
		defer C.free(unsafe.Pointer(es))
		syscall.Close(int(socket))
		return nil, fmt.Errorf("dial error: %v", C.GoString(es))
	}
	defer C.free(unsafe.Pointer(localMAC))
	// Parse the local address.
	var local addr
	if local.mac, err = net.ParseMAC(C.GoString(localMAC)); err != nil {
		return nil, fmt.Errorf("dial error: invalid local MAC address: %s, err: %s", C.GoString(localMAC), err)
	}
	local.port = int(localPort)

	// Connect to the remote address.
	remoteMAC := C.CString(remote.mac.String())
	defer C.free(unsafe.Pointer(remoteMAC))
	remotePort := C.int(remote.port)
	if es := C.bt_connect(socket, remoteMAC, remotePort); es != nil {
		defer C.free(unsafe.Pointer(es))
		return nil, fmt.Errorf("dial error: error connecting to remote address: %s, error: %s", remoteAddr, C.GoString(es))
	}
	return &conn{
		fd:         int(socket),
		localAddr:  &local,
		remoteAddr: remote,
	}, nil
}

// Device is a struct representing an opened Bluetooth device.  It consists of
// a device name, MAC address, id (e.g., 0 for hci0, 1 for hci1 etc.) and a
// device descriptor.
// It is not safe to invoke this type's methods concurrently from multiple
// goroutines.
type Device struct {
	Name       string
	MAC        net.HardwareAddr
	id         int
	descriptor C.int
	leScanChan chan proximity.ScanReading
}

func (d *Device) String() string {
	return fmt.Sprintf("BT_DEVICE(%s, %v)", d.Name, d.MAC)
}

// StartAdvertising starts LE advertising on the Bluetooth device, sending
// one advertising packet after every tick of the provided time interval.
// The payload sent with each advertising packet can be specified via the
// SetAdvertisingPayload method.
// This method may be called again even if advertising is currently enabled,
// in order to adjust the advertising interval.
func (d *Device) StartAdvertising(interval time.Duration) error {
	if es := C.bt_start_le_advertising(d.descriptor, C.int(int64(interval/time.Millisecond))); es != nil {
		defer C.free(unsafe.Pointer(es))
		return fmt.Errorf("error starting LE advertising on device: %v, error: %s", d, C.GoString(es))
	}
	return nil
}

// SetAdvertisingPayload sets the advertising payload that is sent with each
// advertising packet.  This function may be called at any time to adjust the
// payload that is currently being advertised.
func (d *Device) SetAdvertisingPayload(payload string) error {
	if es := C.bt_set_le_advertising_payload(d.descriptor, C.CString(payload)); es != nil {
		defer C.free(unsafe.Pointer(es))
		return fmt.Errorf("error setting advertising payload on device: %v, error: %s", d, C.GoString(es))
	}
	return nil
}

// StopAdvertising stops LE advertising on the Bluetooth device.  If the
// device is not advertising, this function will be a noop.
func (d *Device) StopAdvertising() error {
	if es := C.bt_stop_le_advertising(d.descriptor); es != nil {
		defer C.free(unsafe.Pointer(es))
		return fmt.Errorf("error stopping LE advertising on device: %v, error: %s", d, C.GoString(es))
	}
	return nil
}

// StartScan initiates a Low-Energy scan on the Bluetooth device.  The scan
// will proceed over many duration intervals; within each interval, scan will
// be ON only for a given duration window.  All scan readings encountered
// during scan-ON periods are pushed onto the returned channel.  If the scan
// cannot be started, an error is returned.
func (d *Device) StartScan(scanInterval, scanWindow time.Duration) (<-chan proximity.ScanReading, error) {
	if scanInterval < scanWindow {
		return nil, fmt.Errorf("invalid scan settings: scan interval %d must be greater or equal to scan window %d", scanInterval, scanWindow)
	}
	// Set scan params.
	const (
		passiveScan      = 0x00
		publicAddress    = 0x00
		acceptAllPackets = 0x00
		timeoutMS        = 1000
	)
	if ret, err := C.hci_le_set_scan_parameters(d.descriptor, passiveScan, C.uint16_t(scanInterval/time.Millisecond), C.uint16_t(scanWindow/time.Millisecond), publicAddress, acceptAllPackets, timeoutMS); ret < 0 {
		return nil, fmt.Errorf("error setting LE scan parameters: %v", err)
	}
	// Enable scan.
	const (
		scanEnabled               = 0x01
		disableDuplicateFiltering = 0x00
	)
	if ret, err := C.hci_le_set_scan_enable(d.descriptor, scanEnabled, disableDuplicateFiltering, timeoutMS); ret < 0 {
		return nil, fmt.Errorf("error enabling LE scan: %v", err)
	}
	// Set the event filter options.  We're only interested in LE meta
	// events.
	var fopts C.struct_hci_filter
	C.hci_filter_clear(&fopts)
	C.hci_filter_set_ptype(C.HCI_EVENT_PKT, &fopts)
	C.hci_filter_set_event(C.EVT_LE_META_EVENT, &fopts)
	if ret, err := C.setsockopt(d.descriptor, C.SOL_HCI, C.HCI_FILTER, unsafe.Pointer(&fopts), C.socklen_t(unsafe.Sizeof(fopts))); ret < 0 {
		return nil, fmt.Errorf("couldn't set filter options on socket: %v", err)
	}

	// Start the reading go-routine.
	d.leScanChan = make(chan proximity.ScanReading, 10)
	go d.leScanLoop()
	return d.leScanChan, nil
}

func (d *Device) leScanLoop() {
	defer vlog.Info("LE scan reading goroutine exiting")
	buf := make([]byte, C.HCI_MAX_EVENT_SIZE)
	for {
		// Read one advertising meta event.
		n, err := syscall.Read(int(d.descriptor), buf)
		if err != nil || n < 0 {
			vlog.Errorf("error getting scan readings: %v", err)
			return
		}
		// Get data of interest to us.
		var remoteMAC, remoteName *C.char
		var rssi, done C.int
		if es := C.bt_parse_le_meta_event(unsafe.Pointer(&buf[0]), &remoteMAC, &remoteName, &rssi, &done); es != nil {
			vlog.Errorf("couldn't parse LE meta event: %s", C.GoString(es))
			C.free(unsafe.Pointer(es))
			continue
		}
		if done != 0 { // Scan stopped.
			return
		}
		name := C.GoString(remoteName)
		C.free(unsafe.Pointer(remoteName))
		mac, err := net.ParseMAC(C.GoString(remoteMAC))
		C.free(unsafe.Pointer(remoteMAC))
		if err != nil {
			vlog.Errorf("invalid MAC address: %v", mac)
			continue
		}
		d.leScanChan <- proximity.ScanReading{
			Name:     name,
			MAC:      mac,
			Distance: distanceFromRSSI(int(rssi)),
			Time:     time.Now(),
		}
	}
}

// StopScan stops any Low-Energy scan in progress on the Bluetooth device.
// If the device is not scanning, this function will be a noop.
func (d *Device) StopScan() error {
	// Disable scan.  This will also stop the reading goroutine.
	const (
		scanDisabled              = 0x00
		disableDuplicateFiltering = 0x00
		timeoutMS                 = 1000
	)
	if ret, err := C.hci_le_set_scan_enable(d.descriptor, scanDisabled, disableDuplicateFiltering, timeoutMS); ret < 0 {
		return fmt.Errorf("error disabling LE scan: %v", err)
	}

	close(d.leScanChan)
	return nil
}

// Close closes our handle on the Bluetooth device.  Note that this call doesn't
// stop any operations in progress on the device (e.g., LE advertising) - it
// simply closes the handle to it.
func (d *Device) Close() error {
	if es := C.bt_close_device(d.descriptor); es != nil {
		defer C.free(unsafe.Pointer(es))
		return fmt.Errorf("error closing device %v, error: %s", d, C.GoString(es))
	}
	return nil
}

// distanceFromRSSI computes the distance to the neighboring device using
// the RSSI of that device's advertising packet.
func distanceFromRSSI(rssi int) unit.Distance {
	// We're using the formula (and observed constants) from the following
	// paper:
	//   "Outdoor Localization System Using RSSI Measurement of Wireless
	//    Sensor Network"
	//   by: Oguejiofor O.S., Okorogu V.N., Adewale Abe, and Osuesu B.O
	//   link: http://www.ijitee.org/attachments/File/v2i2/A0359112112.pdf
	//
	// Formula:
	//
	//       RSSI [dBm] = -10n log10(d [m]) + A [dBm]
	//
	//, where:
	//
	//       A = received signal strength at 1m (observed to be -44.8dBm)
	//       n = propagation pathloss exponent (observed to be 2.2)
	//       d = distance (in meters)
	//
	// The final formula for distance (in meters) therefore comes down to:
	//
	//       d = 10^((RSSI / -22) - 2.036)
	//
	return unit.Distance(math.Pow(10.0, (float64(rssi)/-22.0)-2.036)) * unit.Meter
}
