/**********************************************************************
 *
 *  Copyright (C) 2017 The Android Open Source Project
 *  Copyright (C) 2015 Intel Corporation
 *
 *  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.
 *
 **********************************************************************/
#include <base/bind.h>
#include <base/logging.h>
#include <base/threading/thread.h>
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>

#include <sys/ioctl.h>
#include <sys/socket.h>

#include "buffer_allocator.h"
#include "hci_internals.h"
#include "hci_layer.h"
#include "osi/include/compat.h"
#include "osi/include/log.h"
#include "osi/include/osi.h"
#include "osi/include/properties.h"

using base::Thread;

#define BTPROTO_HCI 1
#define HCI_CHANNEL_USER 1
#define HCI_CHANNEL_CONTROL 3
#define HCI_DEV_NONE 0xffff

#define RFKILL_TYPE_BLUETOOTH 2
#define RFKILL_OP_CHANGE_ALL 3

#define MGMT_OP_INDEX_LIST 0x0003
#define MGMT_EV_INDEX_ADDED 0x0004
#define MGMT_EV_COMMAND_COMP 0x0001
#define MGMT_EV_SIZE_MAX 1024
#define MGMT_EV_POLL_TIMEOUT 3000 /* 3000ms */

struct sockaddr_hci {
  sa_family_t hci_family;
  unsigned short hci_dev;
  unsigned short hci_channel;
};

struct rfkill_event {
  uint32_t idx;
  uint8_t type;
  uint8_t op;
  uint8_t soft, hard;
} __attribute__((packed));

struct mgmt_pkt {
  uint16_t opcode;
  uint16_t index;
  uint16_t len;
  uint8_t data[MGMT_EV_SIZE_MAX];
} __attribute__((packed));

struct mgmt_event_read_index {
  uint16_t cc_opcode;
  uint8_t status;
  uint16_t num_intf;
  uint16_t index[0];
} __attribute__((packed));

enum HciPacketType {
  HCI_PACKET_TYPE_UNKNOWN = 0,
  HCI_PACKET_TYPE_COMMAND = 1,
  HCI_PACKET_TYPE_ACL_DATA = 2,
  HCI_PACKET_TYPE_SCO_DATA = 3,
  HCI_PACKET_TYPE_EVENT = 4
};

extern void initialization_complete();
extern void hci_event_received(BT_HDR* packet);
extern void acl_event_received(BT_HDR* packet);
extern void sco_data_received(BT_HDR* packet);

static int bt_vendor_fd = -1;
static int hci_interface;
static int rfkill_en;
static int wait_hcidev(void);
static int rfkill(int block);

int reader_thread_ctrl_fd = -1;
Thread* reader_thread = NULL;

void monitor_socket(int ctrl_fd, int fd) {
  const allocator_t* buffer_allocator = buffer_allocator_get_interface();
  const size_t buf_size = 2000;
  uint8_t buf[buf_size];
  ssize_t len = read(fd, buf, buf_size);

  while (len > 0) {
    if (len == buf_size)
      LOG(FATAL) << "This packet filled buffer, if it have continuation we "
                    "don't know how to merge it, increase buffer size!";

    uint8_t type = buf[0];

    size_t packet_size = buf_size + BT_HDR_SIZE;
    BT_HDR* packet =
        reinterpret_cast<BT_HDR*>(buffer_allocator->alloc(packet_size));
    packet->offset = 0;
    packet->layer_specific = 0;
    packet->len = len - 1;
    memcpy(packet->data, buf + 1, len - 1);

    switch (type) {
      case HCI_PACKET_TYPE_COMMAND:
        packet->event = MSG_HC_TO_STACK_HCI_EVT;
        hci_event_received(packet);
        break;
      case HCI_PACKET_TYPE_ACL_DATA:
        packet->event = MSG_HC_TO_STACK_HCI_ACL;
        acl_event_received(packet);
        break;
      case HCI_PACKET_TYPE_SCO_DATA:
        packet->event = MSG_HC_TO_STACK_HCI_SCO;
        sco_data_received(packet);
        break;
      case HCI_PACKET_TYPE_EVENT:
        packet->event = MSG_HC_TO_STACK_HCI_EVT;
        hci_event_received(packet);
        break;
      default:
        LOG(FATAL) << "Unexpected event type: " << +type;
        break;
    }

    fd_set fds;
    FD_ZERO(&fds);
    FD_SET(ctrl_fd, &fds);
    FD_SET(fd, &fds);
    int res = select(std::max(fd, ctrl_fd) + 1, &fds, NULL, NULL, NULL);
    if (res <= 0) LOG(INFO) << "Nothing more to read";

    if (FD_ISSET(ctrl_fd, &fds)) {
      LOG(INFO) << "exitting";
      return;
    }

    len = read(fd, buf, buf_size);
  }
}

/* TODO: should thread the device waiting and return immedialty */
void hci_initialize() {
  LOG(INFO) << __func__;

  char prop_value[PROPERTY_VALUE_MAX];
  osi_property_get("bluetooth.interface", prop_value, "0");

  errno = 0;
  if (memcmp(prop_value, "hci", 3))
    hci_interface = strtol(prop_value, NULL, 10);
  else
    hci_interface = strtol(prop_value + 3, NULL, 10);
  if (errno) hci_interface = 0;

  LOG(INFO) << "Using interface hci" << +hci_interface;

  osi_property_get("bluetooth.rfkill", prop_value, "1");

  rfkill_en = atoi(prop_value);
  if (rfkill_en) {
    rfkill(0);
  }

  int fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
  CHECK(fd >= 0) << "socket create error" << strerror(errno);

  bt_vendor_fd = fd;

  if (wait_hcidev()) {
    LOG(FATAL) << "HCI interface hci" << +hci_interface << " not found";
  }

  struct sockaddr_hci addr;
  memset(&addr, 0, sizeof(addr));
  addr.hci_family = AF_BLUETOOTH;
  addr.hci_dev = hci_interface;
  addr.hci_channel = HCI_CHANNEL_USER;
  if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
    LOG(FATAL) << "socket bind error " << strerror(errno);
  }

  int sv[2];
  if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) < 0) {
    LOG(FATAL) << "socketpair failed: " << strerror(errno);
  }

  reader_thread_ctrl_fd = sv[0];
  reader_thread = new Thread("hci_sock_reader");
  reader_thread->Start();
  reader_thread->task_runner()->PostTask(
      FROM_HERE, base::Bind(&monitor_socket, sv[1], bt_vendor_fd));

  LOG(INFO) << "HCI device ready";
  initialization_complete();
}

void hci_close() {
  LOG(INFO) << __func__;

  if (bt_vendor_fd != -1) {
    close(bt_vendor_fd);
    bt_vendor_fd = -1;
  }

  if (reader_thread_ctrl_fd != -1) {
    uint8_t msg[] = {1};
    send(reader_thread_ctrl_fd, msg, sizeof(msg), 0);
    reader_thread_ctrl_fd = -1;
  }

  if (reader_thread != NULL) {
    reader_thread->Stop();
    delete reader_thread;
    reader_thread = NULL;
  }

  rfkill(1);
}

void hci_transmit(BT_HDR* packet) {
  uint8_t type;

  CHECK(bt_vendor_fd != -1);

  uint16_t event = packet->event & MSG_EVT_MASK;
  switch (event & MSG_EVT_MASK) {
    case MSG_STACK_TO_HC_HCI_CMD:
      type = 1;
      break;
    case MSG_STACK_TO_HC_HCI_ACL:
      type = 2;
      break;
    case MSG_STACK_TO_HC_HCI_SCO:
      type = 3;
      break;
    default:
      LOG(FATAL) << "Unknown packet type " << event;
      break;
  }

  uint8_t* addr = packet->data + packet->offset - 1;
  uint8_t store = *addr;
  *addr = type;
  size_t ret = write(bt_vendor_fd, addr, packet->len + 1);

  *(addr) = store;

  if (ret != packet->len + 1) LOG(ERROR) << "Should have send whole packet";

  if (ret == -1) LOG(FATAL) << strerror(errno);
}

static int wait_hcidev(void) {
  struct sockaddr_hci addr;
  struct pollfd fds[1];
  struct mgmt_pkt ev;
  int fd;
  int ret = 0;

  LOG(INFO) << __func__;

  fd = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
  if (fd < 0) {
    LOG(ERROR) << "Bluetooth socket error: %s" << strerror(errno);
    return -1;
  }

  memset(&addr, 0, sizeof(addr));
  addr.hci_family = AF_BLUETOOTH;
  addr.hci_dev = HCI_DEV_NONE;
  addr.hci_channel = HCI_CHANNEL_CONTROL;

  if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
    LOG(ERROR) << "HCI Channel Control: " << strerror(errno);
    close(fd);
    return -1;
  }

  fds[0].fd = fd;
  fds[0].events = POLLIN;

  /* Read Controller Index List Command */
  ev.opcode = MGMT_OP_INDEX_LIST;
  ev.index = HCI_DEV_NONE;
  ev.len = 0;

  ssize_t wrote;
  OSI_NO_INTR(wrote = write(fd, &ev, 6));
  if (wrote != 6) {
    LOG(ERROR) << "Unable to write mgmt command: " << strerror(errno);
    ret = -1;
    goto end;
  }

  while (1) {
    int n;
    OSI_NO_INTR(n = poll(fds, 1, MGMT_EV_POLL_TIMEOUT));
    if (n == -1) {
      LOG(ERROR) << "Poll error: " << strerror(errno);
      ret = -1;
      break;
    } else if (n == 0) {
      LOG(ERROR) << "Timeout, no HCI device detected";
      ret = -1;
      break;
    }

    if (fds[0].revents & POLLIN) {
      OSI_NO_INTR(n = read(fd, &ev, sizeof(struct mgmt_pkt)));
      if (n < 0) {
        LOG(ERROR) << "Error reading control channel: " << strerror(errno);
        ret = -1;
        break;
      }

      if (ev.opcode == MGMT_EV_INDEX_ADDED && ev.index == hci_interface) {
        goto end;
      } else if (ev.opcode == MGMT_EV_COMMAND_COMP) {
        struct mgmt_event_read_index* cc;
        int i;

        cc = (struct mgmt_event_read_index*)ev.data;

        if (cc->cc_opcode != MGMT_OP_INDEX_LIST || cc->status != 0) continue;

        for (i = 0; i < cc->num_intf; i++) {
          if (cc->index[i] == hci_interface) goto end;
        }
      }
    }
  }

end:
  close(fd);
  return ret;
}

static int rfkill(int block) {
  struct rfkill_event event;
  int fd;

  LOG(INFO) << __func__;

  fd = open("/dev/rfkill", O_WRONLY);
  if (fd < 0) {
    LOG(ERROR) << "Unable to open /dev/rfkill";
    return -1;
  }

  memset(&event, 0, sizeof(struct rfkill_event));
  event.op = RFKILL_OP_CHANGE_ALL;
  event.type = RFKILL_TYPE_BLUETOOTH;
  event.hard = block;
  event.soft = block;

  ssize_t len;
  OSI_NO_INTR(len = write(fd, &event, sizeof(event)));
  if (len < 0) {
    LOG(ERROR) << "Failed to change rfkill state";
    close(fd);
    return 1;
  }

  close(fd);
  return 0;
}

int hci_open_firmware_log_file() { return INVALID_FD; }

void hci_close_firmware_log_file(int fd) {}

void hci_log_firmware_debug_packet(int fd, BT_HDR* packet) {}
