/******************************************************************************
 *
 *  Copyright (C) 2014 Google, Inc.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

#define LOG_TAG "bt_hci_inject"

#include "hci_inject.h"

#include <base/logging.h>
#include <errno.h>
#include <string.h>

#include "bt_types.h"
#include "buffer_allocator.h"
#include "hci_layer.h"
#include "osi/include/allocator.h"
#include "osi/include/list.h"
#include "osi/include/log.h"
#include "osi/include/osi.h"
#include "osi/include/socket.h"
#include "osi/include/thread.h"

typedef enum {
  HCI_PACKET_COMMAND = 1,
  HCI_PACKET_ACL_DATA = 2,
  HCI_PACKET_SCO_DATA = 3,
  HCI_PACKET_EVENT = 4,
} hci_packet_t;

typedef struct {
  socket_t* socket;
  uint8_t buffer[65536 + 3];  // 2 bytes length prefix, 1 byte type prefix.
  size_t buffer_size;
} client_t;

static bool hci_inject_open(const hci_t* hci_interface);
static void hci_inject_close(void);
static int hci_packet_to_event(hci_packet_t packet);
static void accept_ready(socket_t* socket, void* context);
static void read_ready(socket_t* socket, void* context);
static void client_free(void* ptr);

static const port_t LISTEN_PORT = 8873;

static const hci_inject_t interface = {hci_inject_open, hci_inject_close};

static const hci_t* hci;
static const allocator_t* buffer_allocator;
static socket_t* listen_socket;
static thread_t* thread;
static list_t* clients;

static bool hci_inject_open(const hci_t* hci_interface) {
#if (BT_NET_DEBUG != TRUE)
  return true;  // Disable using network sockets for security reasons
#endif

  CHECK(listen_socket == NULL);
  CHECK(thread == NULL);
  CHECK(clients == NULL);
  CHECK(hci_interface != NULL);

  hci = hci_interface;

  thread = thread_new("hci_inject");
  if (!thread) goto error;

  clients = list_new(client_free);
  if (!clients) goto error;

  listen_socket = socket_new();
  if (!listen_socket) goto error;

  if (!socket_listen(listen_socket, LISTEN_PORT)) goto error;

  socket_register(listen_socket, thread_get_reactor(thread), NULL, accept_ready,
                  NULL);
  return true;

error:;
  interface.close();
  return false;
}

static void hci_inject_close(void) {
#if (BT_NET_DEBUG != TRUE)
  return;  // Disable using network sockets for security reasons
#endif

  socket_free(listen_socket);
  list_free(clients);
  thread_free(thread);

  listen_socket = NULL;
  thread = NULL;
  clients = NULL;
}

static int hci_packet_to_event(hci_packet_t packet) {
  switch (packet) {
    case HCI_PACKET_COMMAND:
      return MSG_STACK_TO_HC_HCI_CMD;
    case HCI_PACKET_ACL_DATA:
      return MSG_STACK_TO_HC_HCI_ACL;
    case HCI_PACKET_SCO_DATA:
      return MSG_STACK_TO_HC_HCI_SCO;
    default:
      LOG_ERROR(LOG_TAG, "%s unsupported packet type: %d", __func__, packet);
      return -1;
  }
}

static void accept_ready(socket_t* socket, UNUSED_ATTR void* context) {
  CHECK(socket != NULL);
  CHECK(socket == listen_socket);

  socket = socket_accept(socket);
  if (!socket) return;

  client_t* client = (client_t*)osi_calloc(sizeof(client_t));

  client->socket = socket;

  if (!list_append(clients, client)) {
    LOG_ERROR(LOG_TAG, "%s unable to add client to list.", __func__);
    client_free(client);
    return;
  }

  socket_register(socket, thread_get_reactor(thread), client, read_ready, NULL);
}

static void read_ready(UNUSED_ATTR socket_t* socket, void* context) {
  CHECK(socket != NULL);
  CHECK(context != NULL);

  client_t* client = (client_t*)context;

  ssize_t ret =
      socket_read(client->socket, client->buffer + client->buffer_size,
                  sizeof(client->buffer) - client->buffer_size);
  if (ret == 0 || (ret == -1 && ret != EWOULDBLOCK && ret != EAGAIN)) {
    list_remove(clients, client);
    return;
  }
  client->buffer_size += ret;

  while (client->buffer_size > 3) {
    uint8_t* buffer = client->buffer;
    hci_packet_t packet_type = (hci_packet_t)buffer[0];
    size_t packet_len = (buffer[2] << 8) | buffer[1];
    size_t frame_len = 3 + packet_len;

    if (client->buffer_size < frame_len) break;

    // TODO(sharvil): validate incoming HCI messages.
    // TODO(sharvil): once we have an HCI parser, we can eliminate
    //   the 2-byte size field since it will be contained in the packet.

    BT_HDR* buf = (BT_HDR*)buffer_allocator->alloc(BT_HDR_SIZE + packet_len);
    if (buf) {
      buf->event = hci_packet_to_event(packet_type);
      buf->offset = 0;
      buf->layer_specific = 0;
      buf->len = packet_len;
      memcpy(buf->data, buffer + 3, packet_len);
      hci->transmit_downward(buf->event, buf);
    } else {
      LOG_ERROR(LOG_TAG, "%s dropping injected packet of length %zu", __func__,
                packet_len);
    }

    size_t remainder = client->buffer_size - frame_len;
    memmove(buffer, buffer + frame_len, remainder);
    client->buffer_size -= frame_len;
  }
}

static void client_free(void* ptr) {
  if (!ptr) return;

  client_t* client = (client_t*)ptr;
  socket_free(client->socket);
  osi_free(client);
}

const hci_inject_t* hci_inject_get_interface() {
  buffer_allocator = buffer_allocator_get_interface();
  return &interface;
}
