package gatt

import (
	"errors"
	"log"
)

// MaxEIRPacketLength is the maximum allowed AdvertisingPacket
// and ScanResponsePacket length.
const MaxEIRPacketLength = 31

// ErrEIRPacketTooLong is the error returned when an AdvertisingPacket
// or ScanResponsePacket is too long.
var ErrEIRPacketTooLong = errors.New("max packet length is 31")

// Advertising data field types
const (
	typeFlags             = 0x01 // Flags
	typeSomeUUID16        = 0x02 // Incomplete List of 16-bit Service Class UUIDs
	typeAllUUID16         = 0x03 // Complete List of 16-bit Service Class UUIDs
	typeSomeUUID32        = 0x04 // Incomplete List of 32-bit Service Class UUIDs
	typeAllUUID32         = 0x05 // Complete List of 32-bit Service Class UUIDs
	typeSomeUUID128       = 0x06 // Incomplete List of 128-bit Service Class UUIDs
	typeAllUUID128        = 0x07 // Complete List of 128-bit Service Class UUIDs
	typeShortName         = 0x08 // Shortened Local Name
	typeCompleteName      = 0x09 // Complete Local Name
	typeTxPower           = 0x0A // Tx Power Level
	typeClassOfDevice     = 0x0D // Class of Device
	typeSimplePairingC192 = 0x0E // Simple Pairing Hash C-192
	typeSimplePairingR192 = 0x0F // Simple Pairing Randomizer R-192
	typeSecManagerTK      = 0x10 // Security Manager TK Value
	typeSecManagerOOB     = 0x11 // Security Manager Out of Band Flags
	typeSlaveConnInt      = 0x12 // Slave Connection Interval Range
	typeServiceSol16      = 0x14 // List of 16-bit Service Solicitation UUIDs
	typeServiceSol128     = 0x15 // List of 128-bit Service Solicitation UUIDs
	typeServiceData16     = 0x16 // Service Data - 16-bit UUID
	typePubTargetAddr     = 0x17 // Public Target Address
	typeRandTargetAddr    = 0x18 // Random Target Address
	typeAppearance        = 0x19 // Appearance
	typeAdvInterval       = 0x1A // Advertising Interval
	typeLEDeviceAddr      = 0x1B // LE Bluetooth Device Address
	typeLERole            = 0x1C // LE Role
	typeServiceSol32      = 0x1F // List of 32-bit Service Solicitation UUIDs
	typeServiceData32     = 0x20 // Service Data - 32-bit UUID
	typeServiceData128    = 0x21 // Service Data - 128-bit UUID
	typeLESecConfirm      = 0x22 // LE Secure Connections Confirmation Value
	typeLESecRandom       = 0x23 // LE Secure Connections Random Value
	typeManufacturerData  = 0xFF // Manufacturer Specific Data
)

// Advertising type flags
const (
	flagLimitedDiscoverable = 0x01 // LE Limited Discoverable Mode
	flagGeneralDiscoverable = 0x02 // LE General Discoverable Mode
	flagLEOnly              = 0x04 // BR/EDR Not Supported. Bit 37 of LMP Feature Mask Definitions (Page 0)
	flagBothController      = 0x08 // Simultaneous LE and BR/EDR to Same Device Capable (Controller).
	flagBothHost            = 0x10 // Simultaneous LE and BR/EDR to Same Device Capable (Host).
)

// FIXME: check the unmarshalling of this data structure.
type ServiceData struct {
	UUID UUID
	Data []byte
}

// This is borrowed from core bluetooth.
// Embedded/Linux folks might be interested in more details.
type Advertisement struct {
	LocalName        string
	ManufacturerData []byte
	ServiceData      []ServiceData
	Services         []UUID
	OverflowService  []UUID
	TxPowerLevel     int
	Connectable      bool
	SolicitedService []UUID
}

// This is only used in Linux port.
func (a *Advertisement) unmarshall(b []byte) error {

	// Utility function for creating a list of uuids.
	uuidList := func(u []UUID, d []byte, w int) []UUID {
		for len(d) > 0 {
			u = append(u, UUID{d[:w]})
			d = d[w:]
		}
		return u
	}

	for len(b) > 0 {
		if len(b) < 2 {
			return errors.New("invalid advertise data")
		}
		l, t := b[0], b[1]
		if len(b) < int(1+l) {
			return errors.New("invalid advertise data")
		}
		d := b[2 : 1+l]
		switch t {
		case typeFlags:
			// TODO: should we do anything about the discoverability here?
		case typeSomeUUID16:
			a.Services = uuidList(a.Services, d, 2)
		case typeAllUUID16:
			a.Services = uuidList(a.Services, d, 2)
		case typeSomeUUID32:
			a.Services = uuidList(a.Services, d, 4)
		case typeAllUUID32:
			a.Services = uuidList(a.Services, d, 4)
		case typeSomeUUID128:
			a.Services = uuidList(a.Services, d, 16)
		case typeAllUUID128:
			a.Services = uuidList(a.Services, d, 16)
		case typeShortName:
			a.LocalName = string(d)
		case typeCompleteName:
			a.LocalName = string(d)
		case typeTxPower:
			a.TxPowerLevel = int(d[0])
		case typeServiceSol16:
			a.SolicitedService = uuidList(a.SolicitedService, d, 2)
		case typeServiceSol128:
			a.SolicitedService = uuidList(a.SolicitedService, d, 16)
		case typeServiceSol32:
			a.SolicitedService = uuidList(a.SolicitedService, d, 4)
		case typeManufacturerData:
			a.ManufacturerData = make([]byte, len(d))
			copy(a.ManufacturerData, d)
		// case typeServiceData16,
		// case typeServiceData32,
		// case typeServiceData128:
		default:
			log.Printf("DATA: [ % X ]", d)
		}
		b = b[1+l:]
	}
	return nil
}

// AdvPacket is an utility to help crafting advertisment or scan response data.
type AdvPacket struct {
	b []byte
}

// Bytes returns an 31-byte array, which contains up to 31 bytes of the packet.
func (a *AdvPacket) Bytes() [31]byte {
	b := [31]byte{}
	copy(b[:], a.b)
	return b
}

// Len returns the length of the packets with a maximum of 31.
func (a *AdvPacket) Len() int {
	if len(a.b) > 31 {
		return 31
	}
	return len(a.b)
}

// AppendField appends a BLE advertising packet field.
// TODO: refuse to append field if it'd make the packet too long.
func (a *AdvPacket) AppendField(typ byte, b []byte) *AdvPacket {
	// A field consists of len, typ, b.
	// Len is 1 byte for typ plus len(b).
	if len(a.b)+2+len(b) > MaxEIRPacketLength {
		b = b[:MaxEIRPacketLength-len(a.b)-2]
	}
	a.b = append(a.b, byte(len(b)+1))
	a.b = append(a.b, typ)
	a.b = append(a.b, b...)
	return a
}

// AppendFlags appends a flag field to the packet.
func (a *AdvPacket) AppendFlags(f byte) *AdvPacket {
	return a.AppendField(typeFlags, []byte{f})
}

// AppendFlags appends a name field to the packet.
// If the name fits in the space, it will be append as a complete name field, otherwise a short name field.
func (a *AdvPacket) AppendName(n string) *AdvPacket {
	typ := byte(typeCompleteName)
	if len(a.b)+2+len(n) > MaxEIRPacketLength {
		typ = byte(typeShortName)
	}
	return a.AppendField(typ, []byte(n))
}

// AppendManufacturerData appends a manufacturer data field to the packet.
func (a *AdvPacket) AppendManufacturerData(id uint16, b []byte) *AdvPacket {
	d := append([]byte{uint8(id), uint8(id >> 8)}, b...)
	return a.AppendField(typeManufacturerData, d)
}

// AppendUUIDFit appends a BLE advertised service UUID
// packet field if it fits in the packet, and reports whether the UUID fit.
func (a *AdvPacket) AppendUUIDFit(u UUID) bool {
	if len(a.b)+2+u.Len() > MaxEIRPacketLength {
		return false
	}
	// Err on the side of safety and assume that there might be
	// other services available: Use typeSomeUUID instead
	// of typeAllUUID.
	// TODO: When we know the full set of services,
	// calculate this exactly, instead of hedging.
	switch u.Len() {
	case 2:
		a.AppendField(typeSomeUUID16, u.b)
	case 16:
		a.AppendField(typeSomeUUID128, u.b)
	}
	return true
}
