/* Copyright 2013 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <stdint.h>
#include <time.h>

using testing::MatchesRegex;
using testing::internal::CaptureStdout;
using testing::internal::GetCapturedStdout;

extern "C" {
#include "cras_hfp_info.c"
#include "sbc_codec_stub.h"
}
static struct hfp_info* info;
static struct cras_iodev dev;
static cras_audio_format format;

static int cras_msbc_plc_create_called;
static int cras_msbc_plc_handle_good_frames_called;
static int cras_msbc_plc_handle_bad_frames_called;

static thread_callback thread_cb;
static void* cb_data;
static timespec ts;

void ResetStubData() {
  sbc_codec_stub_reset();
  cras_msbc_plc_create_called = 0;

  format.format = SND_PCM_FORMAT_S16_LE;
  format.num_channels = 1;
  format.frame_rate = 8000;
  dev.format = &format;
}

namespace {

TEST(HfpInfo, AddRmDev) {
  ResetStubData();

  info = hfp_info_create();
  ASSERT_NE(info, (void*)NULL);
  dev.direction = CRAS_STREAM_OUTPUT;

  /* Test add dev */
  ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));
  ASSERT_TRUE(hfp_info_has_iodev(info));

  /* Test remove dev */
  ASSERT_EQ(0, hfp_info_rm_iodev(info, dev.direction));
  ASSERT_FALSE(hfp_info_has_iodev(info));

  hfp_info_destroy(info);
}

TEST(HfpInfo, AddRmDevInvalid) {
  ResetStubData();

  info = hfp_info_create();
  ASSERT_NE(info, (void*)NULL);

  dev.direction = CRAS_STREAM_OUTPUT;

  /* Remove an iodev which doesn't exist */
  ASSERT_NE(0, hfp_info_rm_iodev(info, dev.direction));

  /* Adding an iodev twice returns error code */
  ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));
  ASSERT_NE(0, hfp_info_add_iodev(info, dev.direction, dev.format));

  hfp_info_destroy(info);
}

TEST(HfpInfo, AcquirePlaybackBuffer) {
  unsigned buffer_frames, buffer_frames2, queued;
  uint8_t* samples;

  ResetStubData();

  info = hfp_info_create();
  ASSERT_NE(info, (void*)NULL);

  hfp_info_start(1, 48, HFP_CODEC_ID_CVSD, info);
  dev.direction = CRAS_STREAM_OUTPUT;
  ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));

  buffer_frames = 500;
  hfp_buf_acquire(info, dev.direction, &samples, &buffer_frames);
  ASSERT_EQ(500, buffer_frames);

  hfp_buf_release(info, dev.direction, 500);
  ASSERT_EQ(500, hfp_buf_queued(info, dev.direction));

  /* Assert the amount of frames of available buffer + queued buf is
   * greater than or equal to the buffer size, 2 bytes per frame
   */
  queued = hfp_buf_queued(info, dev.direction);
  buffer_frames = 500;
  hfp_buf_acquire(info, dev.direction, &samples, &buffer_frames);
  ASSERT_GE(info->playback_buf->used_size / 2, buffer_frames + queued);

  /* Consume all queued data from read buffer */
  buf_increment_read(info->playback_buf, queued * 2);

  queued = hfp_buf_queued(info, dev.direction);
  ASSERT_EQ(0, queued);

  /* Assert consecutive acquire buffer will acquire full used size of buffer */
  buffer_frames = 500;
  hfp_buf_acquire(info, dev.direction, &samples, &buffer_frames);
  hfp_buf_release(info, dev.direction, buffer_frames);

  buffer_frames2 = 500;
  hfp_buf_acquire(info, dev.direction, &samples, &buffer_frames2);
  hfp_buf_release(info, dev.direction, buffer_frames2);

  ASSERT_GE(info->playback_buf->used_size / 2, buffer_frames + buffer_frames2);

  hfp_info_destroy(info);
}

TEST(HfpInfo, AcquireCaptureBuffer) {
  unsigned buffer_frames, buffer_frames2;
  uint8_t* samples;

  ResetStubData();

  info = hfp_info_create();
  ASSERT_NE(info, (void*)NULL);

  hfp_info_start(1, 48, HFP_CODEC_ID_CVSD, info);
  dev.direction = CRAS_STREAM_INPUT;
  ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));

  /* Put fake data 100 bytes(50 frames) in capture buf for test */
  buf_increment_write(info->capture_buf, 100);

  /* Assert successfully acquire and release 100 bytes of data */
  buffer_frames = 50;
  hfp_buf_acquire(info, dev.direction, &samples, &buffer_frames);
  ASSERT_EQ(50, buffer_frames);

  hfp_buf_release(info, dev.direction, buffer_frames);
  ASSERT_EQ(0, hfp_buf_queued(info, dev.direction));

  /* Push fake data to capture buffer */
  buf_increment_write(info->capture_buf, info->capture_buf->used_size - 100);
  buf_increment_write(info->capture_buf, 100);

  /* Assert consecutive acquire call will consume the whole buffer */
  buffer_frames = 1000;
  hfp_buf_acquire(info, dev.direction, &samples, &buffer_frames);
  hfp_buf_release(info, dev.direction, buffer_frames);
  ASSERT_GE(1000, buffer_frames);

  buffer_frames2 = 1000;
  hfp_buf_acquire(info, dev.direction, &samples, &buffer_frames2);
  hfp_buf_release(info, dev.direction, buffer_frames2);

  ASSERT_GE(info->capture_buf->used_size / 2, buffer_frames + buffer_frames2);

  hfp_info_destroy(info);
}

TEST(HfpInfo, HfpReadWriteFD) {
  int rc;
  int sock[2];
  uint8_t sample[480];
  uint8_t* buf;
  unsigned buffer_count;

  ResetStubData();

  ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));

  info = hfp_info_create();
  ASSERT_NE(info, (void*)NULL);

  dev.direction = CRAS_STREAM_INPUT;
  hfp_info_start(sock[1], 48, HFP_CODEC_ID_CVSD, info);
  ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));

  /* Mock the sco fd and send some fake data */
  send(sock[0], sample, 48, 0);

  rc = hfp_read(info);
  ASSERT_EQ(48, rc);

  rc = hfp_buf_queued(info, dev.direction);
  ASSERT_EQ(48 / 2, rc);

  /* Fill the write buffer*/
  buffer_count = info->capture_buf->used_size;
  buf = buf_write_pointer_size(info->capture_buf, &buffer_count);
  buf_increment_write(info->capture_buf, buffer_count);
  ASSERT_NE((void*)NULL, buf);

  rc = hfp_read(info);
  ASSERT_EQ(0, rc);

  ASSERT_EQ(0, hfp_info_rm_iodev(info, dev.direction));
  dev.direction = CRAS_STREAM_OUTPUT;
  ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));

  /* Initial buffer is empty */
  rc = hfp_write(info);
  ASSERT_EQ(0, rc);

  buffer_count = 1024;
  buf = buf_write_pointer_size(info->playback_buf, &buffer_count);
  buf_increment_write(info->playback_buf, buffer_count);

  rc = hfp_write(info);
  ASSERT_EQ(48, rc);

  rc = recv(sock[0], sample, 48, 0);
  ASSERT_EQ(48, rc);

  hfp_info_destroy(info);
}

TEST(HfpInfo, StartHfpInfo) {
  int sock[2];

  ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));

  info = hfp_info_create();
  ASSERT_NE(info, (void*)NULL);

  hfp_info_start(sock[0], 48, HFP_CODEC_ID_CVSD, info);
  ASSERT_EQ(1, hfp_info_running(info));
  ASSERT_EQ(cb_data, (void*)info);

  hfp_info_stop(info);
  ASSERT_EQ(0, hfp_info_running(info));
  ASSERT_EQ(NULL, cb_data);

  hfp_info_destroy(info);
}

TEST(HfpInfo, StartHfpInfoAndRead) {
  int rc;
  int sock[2];
  uint8_t sample[480];

  ResetStubData();

  ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));

  info = hfp_info_create();
  ASSERT_NE(info, (void*)NULL);

  /* Start and send two chunk of fake data */
  hfp_info_start(sock[1], 48, HFP_CODEC_ID_CVSD, info);
  send(sock[0], sample, 48, 0);
  send(sock[0], sample, 48, 0);

  /* Trigger thread callback */
  thread_cb((struct hfp_info*)cb_data, POLLIN);

  dev.direction = CRAS_STREAM_INPUT;
  ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));

  /* Expect no data read, since no idev present at previous thread callback */
  rc = hfp_buf_queued(info, dev.direction);
  ASSERT_EQ(0, rc);

  /* Trigger thread callback after idev added. */
  ts.tv_sec = 0;
  ts.tv_nsec = 5000000;
  thread_cb((struct hfp_info*)cb_data, POLLIN);

  rc = hfp_buf_queued(info, dev.direction);
  ASSERT_EQ(48 / 2, rc);

  /* Assert wait time is unchanged. */
  ASSERT_EQ(0, ts.tv_sec);
  ASSERT_EQ(5000000, ts.tv_nsec);

  hfp_info_stop(info);
  ASSERT_EQ(0, hfp_info_running(info));

  hfp_info_destroy(info);
}

TEST(HfpInfo, StartHfpInfoAndWrite) {
  int rc;
  int sock[2];
  uint8_t sample[480];

  ResetStubData();

  ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));

  info = hfp_info_create();
  ASSERT_NE(info, (void*)NULL);

  hfp_info_start(sock[1], 48, HFP_CODEC_ID_CVSD, info);
  send(sock[0], sample, 48, 0);
  send(sock[0], sample, 48, 0);

  /* Trigger thread callback */
  thread_cb((struct hfp_info*)cb_data, POLLIN);

  /* Without odev in presence, zero packet should be sent. */
  rc = recv(sock[0], sample, 48, 0);
  ASSERT_EQ(48, rc);

  dev.direction = CRAS_STREAM_OUTPUT;
  ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));

  /* Assert queued samples unchanged before output device added */
  ASSERT_EQ(0, hfp_buf_queued(info, dev.direction));

  /* Put some fake data and trigger thread callback again */
  buf_increment_write(info->playback_buf, 1008);
  thread_cb((struct hfp_info*)cb_data, POLLIN);

  /* Assert some samples written */
  rc = recv(sock[0], sample, 48, 0);
  ASSERT_EQ(48, rc);
  ASSERT_EQ(480, hfp_buf_queued(info, dev.direction));

  hfp_info_stop(info);
  hfp_info_destroy(info);
}

void send_mSBC_packet(int fd, unsigned seq, int broken_pkt) {
  /* The first three bytes of hci_sco_buf are h2 header, frame count and mSBC
   * sync word. The second octet of H2 header is composed by 4 bits fixed 0x8
   * and 4 bits sequence number 0000, 0011, 1100, 1111.
   */
  uint8_t headers[4] = {0x08, 0x38, 0xc8, 0xf8};
  uint8_t hci_sco_buf[] = {
      0x01, 0x00, 0xAD, 0xad, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0x00, 0x77,
      0x6d, 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6d, 0xdd, 0xb6, 0xdb,
      0x77, 0x6d, 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6d, 0xdd, 0xb6,
      0xdb, 0x77, 0x6d, 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6d, 0xdd,
      0xb6, 0xdb, 0x77, 0x6d, 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6c};
  struct msghdr msg = {0};
  struct iovec iov;
  struct cmsghdr* cmsg;
  const unsigned int control_size = CMSG_SPACE(sizeof(int));
  char control[control_size] = {0};
  uint8_t pkt_status = 0;

  hci_sco_buf[1] = headers[seq % 4];

  /* Assume typical 60 bytes case. */
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;
  iov.iov_base = hci_sco_buf;
  iov.iov_len = 60;
  msg.msg_control = control;
  msg.msg_controllen = control_size;

  if (broken_pkt)
    pkt_status = 0x11;

  cmsg = CMSG_FIRSTHDR(&msg);
  cmsg->cmsg_level = SOL_BLUETOOTH;
  cmsg->cmsg_type = BT_SCM_PKT_STATUS;
  cmsg->cmsg_len = CMSG_LEN(sizeof(pkt_status));
  memcpy(CMSG_DATA(cmsg), &pkt_status, sizeof(pkt_status));

  sendmsg(fd, &msg, 0);
}

TEST(HfpInfo, StartHfpInfoAndReadMsbc) {
  int sock[2];
  int pkt_count = 0;
  int rc;
  uint8_t sample[480];
  ResetStubData();

  ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));

  set_sbc_codec_decoded_out(MSBC_CODE_SIZE);

  info = hfp_info_create();
  ASSERT_NE(info, (void*)NULL);
  ASSERT_EQ(0, get_msbc_codec_create_called());
  ASSERT_EQ(0, cras_msbc_plc_create_called);

  /* Start and send an mSBC packets with all zero samples */
  hfp_info_start(sock[1], 63, HFP_CODEC_ID_MSBC, info);
  ASSERT_EQ(2, get_msbc_codec_create_called());
  ASSERT_EQ(1, cras_msbc_plc_create_called);
  send_mSBC_packet(sock[0], pkt_count++, 0);

  /* Trigger thread callback */
  thread_cb((struct hfp_info*)cb_data, POLLIN);

  /* Expect one empty mSBC packet is send, because no odev in presence. */
  rc = recv(sock[0], sample, MSBC_PKT_SIZE, 0);
  ASSERT_EQ(MSBC_PKT_SIZE, rc);

  dev.direction = CRAS_STREAM_INPUT;
  ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));

  /* Expect no data read, since no idev present at previous thread callback */
  ASSERT_EQ(0, hfp_buf_queued(info, dev.direction));

  send_mSBC_packet(sock[0], pkt_count, 0);

  /* Trigger thread callback after idev added. */
  thread_cb((struct hfp_info*)cb_data, POLLIN);
  rc = recv(sock[0], sample, MSBC_PKT_SIZE, 0);
  ASSERT_EQ(MSBC_PKT_SIZE, rc);

  ASSERT_EQ(pkt_count * MSBC_CODE_SIZE / 2,
            hfp_buf_queued(info, dev.direction));
  ASSERT_EQ(2, cras_msbc_plc_handle_good_frames_called);
  pkt_count++;
  /* When the third packet is lost, we should call the handle_bad_packet and
   * still have right size of samples queued
   */
  pkt_count++;
  send_mSBC_packet(sock[0], pkt_count, 0);
  thread_cb((struct hfp_info*)cb_data, POLLIN);
  rc = recv(sock[0], sample, MSBC_PKT_SIZE, 0);
  ASSERT_EQ(MSBC_PKT_SIZE, rc);

  /* Packet 1, 2, 4 are all good frames */
  ASSERT_EQ(3, cras_msbc_plc_handle_good_frames_called);
  ASSERT_EQ(1, cras_msbc_plc_handle_bad_frames_called);
  ASSERT_EQ(pkt_count * MSBC_CODE_SIZE / 2,
            hfp_buf_queued(info, dev.direction));
  pkt_count++;
  /* If the erroneous data reporting marks the packet as broken, we should
   * also call the handle_bad_packet and have the right size of samples queued.
   */
  send_mSBC_packet(sock[0], pkt_count, 1);

  set_sbc_codec_decoded_fail(1);

  thread_cb((struct hfp_info*)cb_data, POLLIN);
  rc = recv(sock[0], sample, MSBC_PKT_SIZE, 0);
  ASSERT_EQ(MSBC_PKT_SIZE, rc);

  ASSERT_EQ(3, cras_msbc_plc_handle_good_frames_called);
  ASSERT_EQ(2, cras_msbc_plc_handle_bad_frames_called);
  ASSERT_EQ(pkt_count * MSBC_CODE_SIZE / 2,
            hfp_buf_queued(info, dev.direction));
  pkt_count++;
  /* If we can't decode the packet, we should also call the handle_bad_packet
   * and have the right size of samples queued
   */
  send_mSBC_packet(sock[0], pkt_count, 0);

  set_sbc_codec_decoded_fail(1);

  thread_cb((struct hfp_info*)cb_data, POLLIN);
  rc = recv(sock[0], sample, MSBC_PKT_SIZE, 0);
  ASSERT_EQ(MSBC_PKT_SIZE, rc);

  ASSERT_EQ(3, cras_msbc_plc_handle_good_frames_called);
  ASSERT_EQ(3, cras_msbc_plc_handle_bad_frames_called);
  ASSERT_EQ(pkt_count * MSBC_CODE_SIZE / 2,
            hfp_buf_queued(info, dev.direction));

  hfp_info_stop(info);
  ASSERT_EQ(0, hfp_info_running(info));

  hfp_info_destroy(info);
}

TEST(HfpInfo, StartHfpInfoAndWriteMsbc) {
  int rc;
  int sock[2];
  uint8_t sample[480];

  ResetStubData();

  set_sbc_codec_encoded_out(57);
  ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));

  info = hfp_info_create();
  ASSERT_NE(info, (void*)NULL);

  hfp_info_start(sock[1], 63, HFP_CODEC_ID_MSBC, info);
  send(sock[0], sample, 63, 0);

  /* Trigger thread callback */
  thread_cb((struct hfp_info*)cb_data, POLLIN);

  dev.direction = CRAS_STREAM_OUTPUT;
  ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));

  /* Assert queued samples unchanged before output device added */
  ASSERT_EQ(0, hfp_buf_queued(info, dev.direction));

  /* Put some fake data and trigger thread callback again */
  send(sock[0], sample, 63, 0);
  buf_increment_write(info->playback_buf, 240);
  thread_cb((struct hfp_info*)cb_data, POLLIN);

  /* Assert some samples written */
  rc = recv(sock[0], sample, 60, 0);
  ASSERT_EQ(60, rc);
  ASSERT_EQ(0, hfp_buf_queued(info, dev.direction));

  hfp_info_stop(info);
  hfp_info_destroy(info);
}

TEST(HfpInfo, WBSLoggerPacketStatusDumpBinary) {
  struct packet_status_logger logger;
  char log_regex[64];
  int num_wraps[5] = {0, 0, 0, 1, 1};
  int wp[5] = {40, 150, 162, 100, 32};

  /* Expect the log line wraps at correct length to avoid feedback redact. */
  snprintf(log_regex, 64, "([01D]{%d}\n)*", PACKET_STATUS_LOG_LINE_WRAP);

  packet_status_logger_init(&logger);
  logger.size = PACKET_STATUS_LEN_BYTES * 8;
  for (int i = 0; i < 5; i++) {
    CaptureStdout();
    logger.num_wraps = num_wraps[i];
    logger.wp = wp[i];
    packet_status_logger_dump_binary(&logger);
    EXPECT_THAT(GetCapturedStdout(), MatchesRegex(log_regex));
  }
}

}  // namespace

extern "C" {

struct audio_thread* cras_iodev_list_get_audio_thread() {
  return NULL;
}

void audio_thread_add_events_callback(int fd,
                                      thread_callback cb,
                                      void* data,
                                      int events) {
  thread_cb = cb;
  cb_data = data;
  return;
}

int audio_thread_rm_callback_sync(struct audio_thread* thread, int fd) {
  thread_cb = NULL;
  cb_data = NULL;
  return 0;
}

void audio_thread_rm_callback(int fd) {}

struct cras_msbc_plc* cras_msbc_plc_create() {
  cras_msbc_plc_create_called++;
  return NULL;
}

void cras_msbc_plc_destroy(struct cras_msbc_plc* plc) {}

int cras_msbc_plc_handle_bad_frames(struct cras_msbc_plc* plc,
                                    struct cras_audio_codec* codec,
                                    uint8_t* output) {
  cras_msbc_plc_handle_bad_frames_called++;
  return MSBC_CODE_SIZE;
}

int cras_msbc_plc_handle_good_frames(struct cras_msbc_plc* plc,
                                     const uint8_t* input,
                                     uint8_t* output) {
  cras_msbc_plc_handle_good_frames_called++;
  return MSBC_CODE_SIZE;
}
void packet_status_logger_init(struct packet_status_logger* logger) {}

void packet_status_logger_update(struct packet_status_logger* logger,
                                 bool val) {}
}

int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
