/******************************************************************************
 *
 *  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_mct"

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

#include "bt_vendor_lib.h"
#include "hci_hal.h"
#include "osi/include/eager_reader.h"
#include "osi/include/log.h"
#include "osi/include/osi.h"
#include "osi/include/reactor.h"
#include "vendor.h"

#define HCI_HAL_SERIAL_BUFFER_SIZE 1026

// Our interface and modules we import
static const hci_hal_t interface;
static const hci_hal_callbacks_t *callbacks;
static const vendor_t *vendor;

static thread_t *thread; // Not owned by us

static int uart_fds[CH_MAX];
static eager_reader_t *event_stream;
static eager_reader_t *acl_stream;

static uint16_t transmit_data_on(int fd, uint8_t *data, uint16_t length);
static void event_event_stream_has_bytes(eager_reader_t *reader, void *context);
static void event_acl_stream_has_bytes(eager_reader_t *reader, void *context);

// Interface functions

static bool hal_init(const hci_hal_callbacks_t *upper_callbacks, thread_t *upper_thread) {
  assert(upper_callbacks != NULL);
  assert(upper_thread != NULL);

  callbacks = upper_callbacks;
  thread = upper_thread;
  return true;
}

static bool hal_open() {
  LOG_INFO(LOG_TAG, "%s", __func__);
  // TODO(zachoverflow): close if already open / or don't reopen (maybe at the hci layer level)

  int number_of_ports = vendor->send_command(VENDOR_OPEN_USERIAL, &uart_fds);

  if (number_of_ports != 2 && number_of_ports != 4) {
    LOG_ERROR(LOG_TAG, "%s opened the wrong number of ports: got %d, expected 2 or 4.", __func__, number_of_ports);
    goto error;
  }

  LOG_INFO(LOG_TAG, "%s got uart fds: CMD=%d, EVT=%d, ACL_OUT=%d, ACL_IN=%d",
      __func__, uart_fds[CH_CMD], uart_fds[CH_EVT], uart_fds[CH_ACL_OUT], uart_fds[CH_ACL_IN]);

  if (uart_fds[CH_CMD] == INVALID_FD) {
    LOG_ERROR(LOG_TAG, "%s unable to open the command uart serial port.", __func__);
    goto error;
  }

  if (uart_fds[CH_EVT] == INVALID_FD) {
    LOG_ERROR(LOG_TAG, "%s unable to open the event uart serial port.", __func__);
    goto error;
  }

  if (uart_fds[CH_ACL_OUT] == INVALID_FD) {
    LOG_ERROR(LOG_TAG, "%s unable to open the acl-out uart serial port.", __func__);
    goto error;
  }

  if (uart_fds[CH_ACL_IN] == INVALID_FD) {
    LOG_ERROR(LOG_TAG, "%s unable to open the acl-in uart serial port.", __func__);
    goto error;
  }

  event_stream = eager_reader_new(uart_fds[CH_EVT], &allocator_malloc, HCI_HAL_SERIAL_BUFFER_SIZE, SIZE_MAX, "hci_mct");
  if (!event_stream) {
    LOG_ERROR(LOG_TAG, "%s unable to create eager reader for the event uart serial port.", __func__);
    goto error;
  }

  acl_stream = eager_reader_new(uart_fds[CH_ACL_IN], &allocator_malloc, HCI_HAL_SERIAL_BUFFER_SIZE, SIZE_MAX, "hci_mct");
  if (!event_stream) {
    LOG_ERROR(LOG_TAG, "%s unable to create eager reader for the acl-in uart serial port.", __func__);
    goto error;
  }

  eager_reader_register(event_stream, thread_get_reactor(thread), event_event_stream_has_bytes, NULL);
  eager_reader_register(acl_stream, thread_get_reactor(thread), event_acl_stream_has_bytes, NULL);

  return true;

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

static void hal_close() {
  LOG_INFO(LOG_TAG, "%s", __func__);

  eager_reader_free(event_stream);
  eager_reader_free(acl_stream);
  vendor->send_command(VENDOR_CLOSE_USERIAL, NULL);

  for (int i = 0; i < CH_MAX; i++)
    uart_fds[i] = INVALID_FD;
}

static size_t read_data(serial_data_type_t type, uint8_t *buffer, size_t max_size, bool block) {
  if (type == DATA_TYPE_ACL) {
    return eager_reader_read(acl_stream, buffer, max_size, block);
  } else if (type == DATA_TYPE_EVENT) {
    return eager_reader_read(event_stream, buffer, max_size, block);
  }

  LOG_ERROR(LOG_TAG, "%s invalid data type: %d", __func__, type);
  return 0;
}

static void packet_finished(UNUSED_ATTR serial_data_type_t type) {
  // not needed by this protocol
}

static uint16_t transmit_data(serial_data_type_t type, uint8_t *data, uint16_t length) {
  if (type == DATA_TYPE_ACL) {
    return transmit_data_on(uart_fds[CH_ACL_OUT], data, length);
  } else if (type == DATA_TYPE_COMMAND) {
    return transmit_data_on(uart_fds[CH_CMD], data, length);
  }

  LOG_ERROR(LOG_TAG, "%s invalid data type: %d", __func__, type);
  return 0;
}

// Internal functions

static uint16_t transmit_data_on(int fd, uint8_t *data, uint16_t length) {
  assert(data != NULL);
  assert(length > 0);

  uint16_t transmitted_length = 0;
  while (length > 0) {
    ssize_t ret = write(fd, data + transmitted_length, length);
    switch (ret) {
      case -1:
        LOG_ERROR(LOG_TAG, "In %s, error writing to the serial port with fd %d: %s", __func__, fd, strerror(errno));
        return transmitted_length;
      case 0:
        // If we wrote nothing, don't loop more because we
        // can't go to infinity or beyond
        return transmitted_length;
      default:
        transmitted_length += ret;
        length -= ret;
        break;
    }
  }

  return transmitted_length;
}

static void event_event_stream_has_bytes(UNUSED_ATTR eager_reader_t *reader, UNUSED_ATTR void *context) {
  callbacks->data_ready(DATA_TYPE_EVENT);
}

static void event_acl_stream_has_bytes(UNUSED_ATTR eager_reader_t *reader, UNUSED_ATTR void *context) {
  // No real concept of incoming SCO typed data, just ACL
  callbacks->data_ready(DATA_TYPE_ACL);
}

static const hci_hal_t interface = {
  hal_init,

  hal_open,
  hal_close,

  read_data,
  packet_finished,
  transmit_data,
};

const hci_hal_t *hci_hal_mct_get_interface() {
  vendor = vendor_get_interface();
  return &interface;
}

const hci_hal_t *hci_hal_mct_get_test_interface(vendor_t *vendor_interface) {
  vendor = vendor_interface;
  return &interface;
}
