/******************************************************************************
 *
 *  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 "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 RawAddress& remote_bdaddr, uint16_t psm) {
  CHECK(client != NULL);
  CHECK(psm != 0);
  CHECK(!remote_bdaddr.IsEmpty());
  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, 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;
}
