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

#include "stack/include/l2cap_client.h"

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

#include "btcore/include/bdaddr.h"
#include "osi/include/allocator.h"
#include "osi/include/buffer.h"
#include "osi/include/list.h"
#include "osi/include/log.h"
#include "osi/include/osi.h"
#include "stack/include/l2c_api.h"

struct l2cap_client_t {
  l2cap_client_callbacks_t callbacks;
  void* context;

  uint16_t local_channel_id;
  uint16_t remote_mtu;
  bool configured_self;
  bool configured_peer;
  bool is_congested;
  list_t* outbound_fragments;
};

static void connect_completed_cb(uint16_t local_channel_id,
                                 uint16_t error_code);
static void config_request_cb(uint16_t local_channel_id,
                              tL2CAP_CFG_INFO* requested_parameters);
static void config_completed_cb(uint16_t local_channel_id,
                                tL2CAP_CFG_INFO* negotiated_parameters);
static void disconnect_request_cb(uint16_t local_channel_id, bool ack_required);
static void disconnect_completed_cb(uint16_t local_channel_id,
                                    uint16_t error_code);
static void congestion_cb(uint16_t local_channel_id, bool is_congested);
static void read_ready_cb(uint16_t local_channel_id, BT_HDR* packet);
static void write_completed_cb(uint16_t local_channel_id,
                               uint16_t packets_completed);

static void fragment_packet(l2cap_client_t* client, buffer_t* packet);
static void dispatch_fragments(l2cap_client_t* client);
static l2cap_client_t* find(uint16_t local_channel_id);

// From the Bluetooth Core specification.
static const uint16_t L2CAP_MTU_DEFAULT = 672;
static const uint16_t L2CAP_MTU_MINIMUM = 48;

static const tL2CAP_APPL_INFO l2cap_callbacks = {
    .pL2CA_ConnectCfm_Cb = connect_completed_cb,
    .pL2CA_ConfigInd_Cb = config_request_cb,
    .pL2CA_ConfigCfm_Cb = config_completed_cb,
    .pL2CA_DisconnectInd_Cb = disconnect_request_cb,
    .pL2CA_DisconnectCfm_Cb = disconnect_completed_cb,
    .pL2CA_CongestionStatus_Cb = congestion_cb,
    .pL2CA_DataInd_Cb = read_ready_cb,
    .pL2CA_TxComplete_Cb = write_completed_cb,
};

static list_t*
    l2cap_clients;  // A list of l2cap_client_t. Container does not own objects.

buffer_t* l2cap_buffer_new(size_t size) {
  buffer_t* buf = buffer_new(size + L2CAP_MIN_OFFSET);
  buffer_t* slice = NULL;
  if (buf) slice = buffer_new_slice(buf, size);
  buffer_free(buf);
  return slice;
}

l2cap_client_t* l2cap_client_new(const l2cap_client_callbacks_t* callbacks,
                                 void* context) {
  CHECK(callbacks != NULL);
  CHECK(callbacks->connected != NULL);
  CHECK(callbacks->disconnected != NULL);
  CHECK(callbacks->read_ready != NULL);
  CHECK(callbacks->write_ready != NULL);

  if (!l2cap_clients) {
    l2cap_clients = list_new(NULL);
    if (!l2cap_clients) {
      LOG_ERROR(LOG_TAG, "%s unable to allocate space for L2CAP client list.",
                __func__);
      return NULL;
    }
  }

  l2cap_client_t* ret = (l2cap_client_t*)osi_calloc(sizeof(l2cap_client_t));

  ret->callbacks = *callbacks;
  ret->context = context;

  ret->remote_mtu = L2CAP_MTU_DEFAULT;
  ret->outbound_fragments = list_new(NULL);

  list_append(l2cap_clients, ret);

  return ret;
}

void l2cap_client_free(l2cap_client_t* client) {
  if (!client) return;

  list_remove(l2cap_clients, client);
  l2cap_client_disconnect(client);
  list_free(client->outbound_fragments);
  osi_free(client);
}

bool l2cap_client_connect(l2cap_client_t* client,
                          const bt_bdaddr_t* remote_bdaddr, uint16_t psm) {
  CHECK(client != NULL);
  CHECK(remote_bdaddr != NULL);
  CHECK(psm != 0);
  CHECK(!bdaddr_is_empty(remote_bdaddr));
  CHECK(client->local_channel_id == 0);
  CHECK(!client->configured_self);
  CHECK(!client->configured_peer);
  CHECK(!L2C_INVALID_PSM(psm));

  client->local_channel_id = L2CA_ConnectReq(psm, (uint8_t*)remote_bdaddr);
  if (!client->local_channel_id) {
    LOG_ERROR(LOG_TAG, "%s unable to create L2CAP connection.", __func__);
    return false;
  }

  L2CA_SetConnectionCallbacks(client->local_channel_id, &l2cap_callbacks);
  return true;
}

void l2cap_client_disconnect(l2cap_client_t* client) {
  CHECK(client != NULL);

  if (client->local_channel_id && !L2CA_DisconnectReq(client->local_channel_id))
    LOG_ERROR(LOG_TAG, "%s unable to send disconnect message for LCID 0x%04x.",
              __func__, client->local_channel_id);

  client->local_channel_id = 0;
  client->remote_mtu = L2CAP_MTU_DEFAULT;
  client->configured_self = false;
  client->configured_peer = false;
  client->is_congested = false;

  for (const list_node_t* node = list_begin(client->outbound_fragments);
       node != list_end(client->outbound_fragments); node = list_next(node))
    osi_free(list_node(node));

  list_clear(client->outbound_fragments);
}

bool l2cap_client_is_connected(const l2cap_client_t* client) {
  CHECK(client != NULL);

  return client->local_channel_id != 0 && client->configured_self &&
         client->configured_peer;
}

bool l2cap_client_write(l2cap_client_t* client, buffer_t* packet) {
  CHECK(client != NULL);
  CHECK(packet != NULL);
  CHECK(l2cap_client_is_connected(client));

  if (client->is_congested) return false;

  fragment_packet(client, packet);
  dispatch_fragments(client);
  return true;
}

static void connect_completed_cb(uint16_t local_channel_id,
                                 uint16_t error_code) {
  CHECK(local_channel_id != 0);

  l2cap_client_t* client = find(local_channel_id);
  if (!client) {
    LOG_ERROR(LOG_TAG, "%s unable to find L2CAP client for LCID 0x%04x.",
              __func__, local_channel_id);
    return;
  }

  if (error_code != L2CAP_CONN_OK) {
    LOG_ERROR(LOG_TAG, "%s error connecting L2CAP channel: %d.", __func__,
              error_code);
    client->callbacks.disconnected(client, client->context);
    return;
  }

  // Use default L2CAP parameters.
  tL2CAP_CFG_INFO desired_parameters;
  memset(&desired_parameters, 0, sizeof(desired_parameters));
  if (!L2CA_ConfigReq(local_channel_id, &desired_parameters)) {
    LOG_ERROR(LOG_TAG, "%s error sending L2CAP config parameters.", __func__);
    client->callbacks.disconnected(client, client->context);
  }
}

static void config_request_cb(uint16_t local_channel_id,
                              tL2CAP_CFG_INFO* requested_parameters) {
  tL2CAP_CFG_INFO response;
  l2cap_client_t* client = find(local_channel_id);

  if (!client) {
    LOG_ERROR(LOG_TAG, "%s unable to find L2CAP client matching LCID 0x%04x.",
              __func__, local_channel_id);
    return;
  }

  memset(&response, 0, sizeof(response));
  response.result = L2CAP_CFG_OK;

  if (requested_parameters->mtu_present) {
    // Make sure the peer chose an MTU at least as large as the minimum L2CAP
    // MTU defined by the Bluetooth Core spec.
    if (requested_parameters->mtu < L2CAP_MTU_MINIMUM) {
      response.mtu = L2CAP_MTU_MINIMUM;
      response.mtu_present = true;
      response.result = L2CAP_CFG_UNACCEPTABLE_PARAMS;
    } else {
      client->remote_mtu = requested_parameters->mtu;
    }
  }

  if (requested_parameters->fcr_present) {
    if (requested_parameters->fcr.mode != L2CAP_FCR_BASIC_MODE) {
      response.fcr_present = true;
      response.fcr = requested_parameters->fcr;
      response.fcr.mode = L2CAP_FCR_BASIC_MODE;
      response.result = L2CAP_CFG_UNACCEPTABLE_PARAMS;
    }
  }

  if (!L2CA_ConfigRsp(local_channel_id, &response)) {
    LOG_ERROR(LOG_TAG, "%s unable to send config response for LCID 0x%04x.",
              __func__, local_channel_id);
    l2cap_client_disconnect(client);
    return;
  }

  // If we've configured both endpoints, let the listener know we've connected.
  client->configured_peer = true;
  if (l2cap_client_is_connected(client))
    client->callbacks.connected(client, client->context);
}

static void config_completed_cb(uint16_t local_channel_id,
                                tL2CAP_CFG_INFO* negotiated_parameters) {
  l2cap_client_t* client = find(local_channel_id);

  if (!client) {
    LOG_ERROR(LOG_TAG, "%s unable to find L2CAP client matching LCID 0x%04x.",
              __func__, local_channel_id);
    return;
  }

  switch (negotiated_parameters->result) {
    // We'll get another configuration response later.
    case L2CAP_CFG_PENDING:
      break;

    case L2CAP_CFG_UNACCEPTABLE_PARAMS:
      // TODO: see if we can renegotiate parameters instead of dropping the
      // connection.
      LOG_WARN(
          LOG_TAG,
          "%s dropping L2CAP connection due to unacceptable config parameters.",
          __func__);
      l2cap_client_disconnect(client);
      break;

    case L2CAP_CFG_OK:
      // If we've configured both endpoints, let the listener know we've
      // connected.
      client->configured_self = true;
      if (l2cap_client_is_connected(client))
        client->callbacks.connected(client, client->context);
      break;

    // Failure, no further parameter negotiation possible.
    default:
      LOG_WARN(LOG_TAG,
               "%s L2CAP parameter negotiation failed with error code %d.",
               __func__, negotiated_parameters->result);
      l2cap_client_disconnect(client);
      break;
  }
}

static void disconnect_request_cb(uint16_t local_channel_id,
                                  bool ack_required) {
  l2cap_client_t* client = find(local_channel_id);
  if (!client) {
    LOG_ERROR(LOG_TAG, "%s unable to find L2CAP client with LCID 0x%04x.",
              __func__, local_channel_id);
    return;
  }

  if (ack_required) L2CA_DisconnectRsp(local_channel_id);

  // We already sent a disconnect response so this LCID is now invalid.
  client->local_channel_id = 0;
  l2cap_client_disconnect(client);

  client->callbacks.disconnected(client, client->context);
}

static void disconnect_completed_cb(uint16_t local_channel_id,
                                    UNUSED_ATTR uint16_t error_code) {
  CHECK(local_channel_id != 0);

  l2cap_client_t* client = find(local_channel_id);
  if (!client) {
    LOG_ERROR(LOG_TAG, "%s unable to find L2CAP client with LCID 0x%04x.",
              __func__, local_channel_id);
    return;
  }

  client->local_channel_id = 0;
  l2cap_client_disconnect(client);

  client->callbacks.disconnected(client, client->context);
}

static void congestion_cb(uint16_t local_channel_id, bool is_congested) {
  CHECK(local_channel_id != 0);

  l2cap_client_t* client = find(local_channel_id);
  if (!client) {
    LOG_ERROR(LOG_TAG, "%s unable to find L2CAP client matching LCID 0x%04x.",
              __func__, local_channel_id);
    return;
  }

  client->is_congested = is_congested;

  if (!is_congested) {
    // If we just decongested, dispatch whatever we have left over in our queue.
    // Once that's done, if we're still decongested, notify the listener so it
    // can start writing again.
    dispatch_fragments(client);
    if (!client->is_congested)
      client->callbacks.write_ready(client, client->context);
  }
}

static void read_ready_cb(uint16_t local_channel_id, BT_HDR* packet) {
  CHECK(local_channel_id != 0);

  l2cap_client_t* client = find(local_channel_id);
  if (!client) {
    LOG_ERROR(LOG_TAG, "%s unable to find L2CAP client matching LCID 0x%04x.",
              __func__, local_channel_id);
    return;
  }

  // TODO(sharvil): eliminate copy from BT_HDR.
  buffer_t* buffer = buffer_new(packet->len);
  memcpy(buffer_ptr(buffer), packet->data + packet->offset, packet->len);
  osi_free(packet);

  client->callbacks.read_ready(client, buffer, client->context);
  buffer_free(buffer);
}

static void write_completed_cb(UNUSED_ATTR uint16_t local_channel_id,
                               UNUSED_ATTR uint16_t packets_completed) {
  // Do nothing. We update congestion state based on the congestion callback
  // and we've already removed items from outbound_fragments list so we don't
  // really care how many packets were successfully dispatched.
}

static void fragment_packet(l2cap_client_t* client, buffer_t* packet) {
  CHECK(client != NULL);
  CHECK(packet != NULL);

  // TODO(sharvil): eliminate copy into BT_HDR.
  BT_HDR* bt_packet = static_cast<BT_HDR*>(
      osi_malloc(buffer_length(packet) + L2CAP_MIN_OFFSET + sizeof(BT_HDR)));
  bt_packet->offset = L2CAP_MIN_OFFSET;
  bt_packet->len = buffer_length(packet);
  memcpy(bt_packet->data + bt_packet->offset, buffer_ptr(packet),
         buffer_length(packet));

  for (;;) {
    if (bt_packet->len <= client->remote_mtu) {
      if (bt_packet->len > 0)
        list_append(client->outbound_fragments, bt_packet);
      else
        osi_free(bt_packet);
      break;
    }

    BT_HDR* fragment = static_cast<BT_HDR*>(
        osi_malloc(client->remote_mtu + L2CAP_MIN_OFFSET + sizeof(BT_HDR)));
    fragment->offset = L2CAP_MIN_OFFSET;
    fragment->len = client->remote_mtu;
    memcpy(fragment->data + fragment->offset,
           bt_packet->data + bt_packet->offset, client->remote_mtu);

    list_append(client->outbound_fragments, fragment);

    bt_packet->offset += client->remote_mtu;
    bt_packet->len -= client->remote_mtu;
  }
}

static void dispatch_fragments(l2cap_client_t* client) {
  CHECK(client != NULL);
  CHECK(!client->is_congested);

  while (!list_is_empty(client->outbound_fragments)) {
    BT_HDR* packet = (BT_HDR*)list_front(client->outbound_fragments);
    list_remove(client->outbound_fragments, packet);

    switch (L2CA_DataWrite(client->local_channel_id, packet)) {
      case L2CAP_DW_CONGESTED:
        client->is_congested = true;
        return;

      case L2CAP_DW_FAILED:
        LOG_ERROR(LOG_TAG,
                  "%s error writing data to L2CAP connection LCID 0x%04x; "
                  "disconnecting.",
                  __func__, client->local_channel_id);
        l2cap_client_disconnect(client);
        return;

      case L2CAP_DW_SUCCESS:
        break;
    }
  }
}

static l2cap_client_t* find(uint16_t local_channel_id) {
  CHECK(local_channel_id != 0);

  for (const list_node_t* node = list_begin(l2cap_clients);
       node != list_end(l2cap_clients); node = list_next(node)) {
    l2cap_client_t* client = (l2cap_client_t*)list_node(node);
    if (client->local_channel_id == local_channel_id) return client;
  }

  return NULL;
}
