/*
 * BRLTTY - A background process providing access to the console screen (when in
 *          text mode) for a blind person using a refreshable braille display.
 *
 * Copyright (C) 1995-2023 by The BRLTTY Developers.
 *
 * BRLTTY comes with ABSOLUTELY NO WARRANTY.
 *
 * This is free software, placed under the terms of the
 * GNU Lesser General Public License, as published by the Free Software
 * Foundation; either version 2.1 of the License, or (at your option) any
 * later version. Please see the file LICENSE-LGPL for details.
 *
 * Web Page: http://brltty.app/
 *
 * This software is maintained by Dave Mielke <dave@mielke.cc>.
 */

#define _WIN32_WINNT _WIN32_WINNT_VISTA
#define __USE_W32_SOCKETS

#pragma pack(push,2)
#include <winsock2.h>
#include <ws2bth.h>
#include <nspapi.h>
#pragma pack(pop)

#include "prologue.h"

#include <string.h>
#include <errno.h>

#if defined(AF_BTH)
#ifndef PF_BTH
#define PF_BTH AF_BTH
#endif /* PF_BTH */

#elif defined(PF_BTH)
#ifndef AF_BTH
#define AF_BTH PF_BTH
#endif /* AF_BTH */

#else /* bluetooth address/protocol family definitions */
#define AF_BTH 32
#define PF_BTH AF_BTH
#warning using hard-coded value for Bluetooth socket address and protocol family constants
#endif /* bluetooth address/protocol family definitions */

#ifndef NS_BTH
#define NS_BTH 16
#warning using hard-coded value for Bluetooth namespace constant
#endif /* NS_BTH */

#if defined(__CYGWIN__) && !defined(__CYGWIN32__)
#define IOCTLSOCKET_ARGUMENT_TYPE unsigned int
#else /* ioctlcontrol argument type */
#define IOCTLSOCKET_ARGUMENT_TYPE u_long
#endif /* ioctlcontrol argument type */

#include "log.h"
#include "timing.h"
#include "bitfield.h"
#include "io_bluetooth.h"
#include "bluetooth_internal.h"

struct BluetoothConnectionExtensionStruct {
  SOCKET socket;
  SOCKADDR_BTH local;
  SOCKADDR_BTH remote;
};

static void
bthSetErrno (DWORD error, const char *action, const DWORD *exceptions) {
  if (exceptions) {
    const DWORD *exception = exceptions;

    while (*exception != NO_ERROR) {
      if (error == *exception) goto isException;
      exception += 1;
    }
  }

  logWindowsError(error, action);
isException:
  setErrno(error);
}

static DWORD
bthSocketError (const char *action, const DWORD *exceptions) {
  DWORD error = WSAGetLastError();

  bthSetErrno(error, action, exceptions);
  return error;
}

static int
bthStartSockets (void) {
  WSADATA wsa;
  int result = WSAStartup(MAKEWORD(2, 2), &wsa);

  if (!result) return 1;
  bthSetErrno(result, "WSA startup", NULL);
  return 0;
}

BluetoothConnectionExtension *
bthNewConnectionExtension (uint64_t bda) {
  BluetoothConnectionExtension *bcx;

  if ((bcx = malloc(sizeof(*bcx)))) {
    memset(bcx, 0, sizeof(*bcx));

    bcx->local.addressFamily = AF_BTH;
    bcx->local.btAddr = BTH_ADDR_NULL;
    bcx->local.port = 0;

    bcx->remote.addressFamily = AF_BTH;
    bcx->remote.btAddr = bda;
    bcx->remote.port = 0;

    bcx->socket = INVALID_SOCKET;
    return bcx;
  } else {
    logMallocError();
  }

  return NULL;
}

void
bthReleaseConnectionExtension (BluetoothConnectionExtension *bcx) {
  if (bcx->socket != INVALID_SOCKET) {
    closesocket(bcx->socket);
    bcx->socket = INVALID_SOCKET;
  }

  free(bcx);
}

int
bthOpenChannel (BluetoothConnectionExtension *bcx, uint8_t channel, int timeout) {
  bcx->remote.port = channel;

  if (bthStartSockets()) {
    if ((bcx->socket = socket(PF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM)) != INVALID_SOCKET) {
      if (bind(bcx->socket, (SOCKADDR *)&bcx->local, sizeof(bcx->local)) != SOCKET_ERROR) {
        if (connect(bcx->socket, (SOCKADDR *)&bcx->remote, sizeof(bcx->remote)) != SOCKET_ERROR) {
          IOCTLSOCKET_ARGUMENT_TYPE nonblocking = 1;

          if (ioctlsocket(bcx->socket, FIONBIO, &nonblocking) != SOCKET_ERROR) {
            return 1;
          } else {
            bthSocketError("RFCOMM nonblocking", NULL);
          }
        } else {
          static const DWORD exceptions[] = {
            ERROR_HOST_DOWN,
            ERROR_HOST_UNREACHABLE,
            NO_ERROR
          };

          bthSocketError("RFCOMM connect", exceptions);
        }
      } else {
        bthSocketError("RFCOMM bind", NULL);
      }

      closesocket(bcx->socket);
      bcx->socket = INVALID_SOCKET;
    } else {
      bthSocketError("RFCOMM socket", NULL);
    }
  }

  return 0;
}

typedef union {
  double ensureCorrectAlignment;
  unsigned char ensureAdequateSize[0X1000];
  WSAQUERYSET querySet;
} BluetoothServiceLookupResult;

static int
bthPerformServiceLookup (
  BluetoothServiceLookupResult *result,
  ULONGLONG address, GUID *guid,
  DWORD beginFlags, DWORD nextFlags
) {
  int found = 0;

  if (bthStartSockets()) {
    SOCKADDR_BTH socketAddress = {
      .addressFamily = AF_BTH,
      .btAddr = address
    };

    char addressString[0X100];
    DWORD addressLength = sizeof(addressString);

    if (WSAAddressToString((SOCKADDR *)&socketAddress, sizeof(socketAddress),
                            NULL,
                            addressString, &addressLength) != SOCKET_ERROR) {
      HANDLE handle;

      CSADDR_INFO csa[] = {
        {
          .RemoteAddr = {
            .lpSockaddr = (SOCKADDR *)&socketAddress,
            .iSockaddrLength = sizeof(socketAddress)
          }
        }
      };

      WSAQUERYSET restrictions = {
        .dwNameSpace = NS_BTH,
        .lpszContext = addressString,
        .lpcsaBuffer = csa,
        .dwNumberOfCsAddrs = ARRAY_COUNT(csa),
        .lpServiceClassId = guid,
        .dwSize = sizeof(restrictions)
      };

      if (WSALookupServiceBegin(&restrictions, (LUP_FLUSHCACHE | beginFlags), &handle) != SOCKET_ERROR) {
        DWORD resultLength = sizeof(*result);

        if (WSALookupServiceNext(handle, nextFlags, &resultLength, &result->querySet) != SOCKET_ERROR) {
          found = 1;
        } else {
          static const DWORD exceptions[] = {
#ifdef WSA_E_NO_MORE
            WSA_E_NO_MORE,
#endif /* WSA_E_NO_MORE */

#ifdef WSAENOMORE
            WSAENOMORE,
#endif /* WSAENOMORE */

            NO_ERROR
          };

          bthSocketError("WSALookupServiceNext", exceptions);
        }

        if (WSALookupServiceEnd(handle) == SOCKET_ERROR) {
          bthSocketError("WSALookupServiceEnd", NULL);
        }
      } else {
        static const DWORD exceptions[] = {
          WSASERVICE_NOT_FOUND,
          NO_ERROR
        };

        bthSocketError("WSALookupServiceBegin", exceptions);
      }
    } else {
      bthSocketError("WSAAddressToString", NULL);
    }
  }

  return found;
}

int
bthDiscoverChannel (
  uint8_t *channel, BluetoothConnectionExtension *bcx,
  const void *uuidBytes, size_t uuidLength,
  int timeout
) {
  GUID guid;

  memcpy(&guid, uuidBytes, sizeof(guid));
  putNativeEndian32((uint32_t *)&guid.Data1, getBigEndian32(guid.Data1));
  putNativeEndian16((uint16_t *)&guid.Data2, getBigEndian16(guid.Data2));
  putNativeEndian16((uint16_t *)&guid.Data3, getBigEndian16(guid.Data3));

#if 1
  {
    BluetoothServiceLookupResult result;

    if (bthPerformServiceLookup(&result, bcx->remote.btAddr, &guid, 0, LUP_RETURN_ADDR)) {
      SOCKADDR_BTH *bth = (SOCKADDR_BTH *)result.querySet.lpcsaBuffer[0].RemoteAddr.lpSockaddr;

      if (bth->port) {
        *channel = bth->port;
        return 1;
      }
    }

    return 0;
  }
#else /* discover channel */
  memcpy(&bcx->remote.serviceClassId, &guid, sizeof(bcx->remote.serviceClassId));
  *channel = 0;
  return 1;
#endif /* discover channel */
}

int
bthMonitorInput (BluetoothConnection *connection, AsyncMonitorCallback *callback, void *data) {
  return 0;
}

int
bthPollInput (BluetoothConnectionExtension *bcx, int timeout) {
  fd_set input;
  TIMEVAL time;

  FD_ZERO(&input);
  FD_SET(bcx->socket, &input);

  memset(&time, 0, sizeof(time));
  time.tv_sec = timeout / MSECS_PER_SEC;
  time.tv_usec = (timeout % MSECS_PER_SEC) * USECS_PER_MSEC;

  switch (select(bcx->socket+1, &input, NULL, NULL, &time)) {
    case SOCKET_ERROR:
      bthSocketError("RFCOMM wait", NULL);
      break;

    case 0:
      errno = EAGAIN;
      break;

    default:
      return 1;
  }

  return 0;
}

ssize_t
bthGetData (
  BluetoothConnectionExtension *bcx, void *buffer, size_t size,
  int initialTimeout, int subsequentTimeout
) {
  size_t count = size;

  if (count) {
    char *to = buffer;

    while (1) {
      int result = recv(bcx->socket, to, count, 0);

      if (result != SOCKET_ERROR) {
        to += result;
        if (!(count -= result)) break;
      } else {
        static const DWORD exceptions[] = {
          WSAEWOULDBLOCK,
          NO_ERROR
        };

        DWORD error = bthSocketError("RFCOMM read", exceptions);
        if (error != WSAEWOULDBLOCK) return -1;
      }

      {
        int timeout = (to == buffer)? initialTimeout: subsequentTimeout;

        if (!timeout) break;
        if (!bthPollInput(bcx, timeout)) return -1;
      }
    }
  }

  if (size == count) errno = EAGAIN;
  return size - count;
}

ssize_t
bthPutData (BluetoothConnectionExtension *bcx, const void *buffer, size_t size) {
  const char *from = buffer;
  size_t count = size;

  while (count) {
    int result = send(bcx->socket, from, count, 0);

    if (result == SOCKET_ERROR) {
      bthSocketError("RFCOMM write", NULL);
      return -1;
    }

    from += result;
    count -= result;
  }

  return size;
}

char *
bthObtainDeviceName (uint64_t bda, int timeout) {
  BluetoothServiceLookupResult result;

  if (bthPerformServiceLookup(&result, bda, NULL, LUP_CONTAINERS, LUP_RETURN_NAME)) {
    char *name = strdup(result.querySet.lpszServiceInstanceName);

    if (name) {
      return name;
    } else {
      logMallocError();
    }
  }

  return NULL;
}

void
bthProcessDiscoveredDevices (
  DiscoveredBluetoothDeviceTester *testDevice, void *data
) {
  if (bthStartSockets()) {
    HANDLE handle;

    WSAQUERYSET restrictions = {
      .dwNameSpace = NS_BTH,
      .dwSize = sizeof(restrictions)
    };

    if (WSALookupServiceBegin(&restrictions, LUP_CONTAINERS, &handle) != SOCKET_ERROR) {
      while (1) {
        BluetoothServiceLookupResult result;
        DWORD resultLength = sizeof(result);

        if (WSALookupServiceNext(handle,
                                 (LUP_RETURN_ADDR | LUP_RETURN_NAME | LUP_RETURN_BLOB),
                                 &resultLength, &result.querySet) == SOCKET_ERROR) {
          static const DWORD exceptions[] = {
#ifdef WSA_E_NO_MORE
            WSA_E_NO_MORE,
#endif /* WSA_E_NO_MORE */

#ifdef WSAENOMORE
            WSAENOMORE,
#endif /* WSAENOMORE */

            NO_ERROR
          };

          bthSocketError("WSALookupServiceNext", exceptions);
          break;
        }

        if (result.querySet.dwNumberOfCsAddrs == 1) {
          DiscoveredBluetoothDevice device;
          memset(&device, 0, sizeof(device));

          {
            BTH_ADDR address = ((SOCKADDR_BTH *)result.querySet.lpcsaBuffer->RemoteAddr.lpSockaddr)->btAddr;
            device.address = ((uint64_t)GET_NAP(address) << 0X20) | (uint64_t)GET_SAP(address);
          }

          {
            char *name = result.querySet.lpszServiceInstanceName;
            if (name && *name) device.name = name;
          }

          {
            BTH_DEVICE_INFO *info = (BTH_DEVICE_INFO *)result.querySet.lpBlob->pBlobData;
            device.paired = !!(info->flags & BDIF_PAIRED);
          }

          if (testDevice(&device, data)) break;
        }
      }

      if (WSALookupServiceEnd(handle) == SOCKET_ERROR) {
        bthSocketError("WSALookupServiceEnd", NULL);
      }
    } else {
      static const DWORD exceptions[] = {
        WSASERVICE_NOT_FOUND,
        NO_ERROR
      };

      bthSocketError("WSALookupServiceBegin", exceptions);
    }
  }
}
