/******************************************************************************
 *
 *  Copyright 2009-2012 Broadcom 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.
 *
 ******************************************************************************/

/*******************************************************************************
 *
 *  Filename:      btif_sock_thread.cc
 *
 *  Description:   socket select thread
 *
 ******************************************************************************/

#define LOG_TAG "bt_btif_sock"

#include "btif_sock_thread.h"

#include <alloca.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <features.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/poll.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <time.h>
#include <unistd.h>

#include <mutex>
#include <optional>
#include <string>

#include "bta_api.h"
#include "btif_common.h"
#include "btif_sock.h"
#include "btif_sock_util.h"
#include "btif_util.h"
#include "osi/include/socket_utils/sockets.h"

#define asrt(s)                                                              \
  do {                                                                       \
    if (!(s))                                                                \
      APPL_TRACE_ERROR("## %s assert %s failed at line:%d ##", __func__, #s, \
                       __LINE__)                                             \
  } while (0)

#define MAX_THREAD 8
#define MAX_POLL 64
#define POLL_EXCEPTION_EVENTS (POLLHUP | POLLRDHUP | POLLERR | POLLNVAL)
#define IS_EXCEPTION(e) ((e)&POLL_EXCEPTION_EVENTS)
#define IS_READ(e) ((e)&POLLIN)
#define IS_WRITE(e) ((e)&POLLOUT)
/*cmd executes in socket poll thread */
#define CMD_WAKEUP 1
#define CMD_EXIT 2
#define CMD_ADD_FD 3
#define CMD_REMOVE_FD 4
#define CMD_USER_PRIVATE 5

struct poll_slot_t {
  struct pollfd pfd;
  uint32_t user_id;
  int type;
  int flags;
};
struct thread_slot_t {
  int cmd_fdr, cmd_fdw;
  int poll_count;
  poll_slot_t ps[MAX_POLL];
  int psi[MAX_POLL];  // index of poll slot
  std::optional<pthread_t> thread_id;
  btsock_signaled_cb callback;
  btsock_cmd_cb cmd_callback;
  int used;
};
static thread_slot_t ts[MAX_THREAD];

static void* sock_poll_thread(void* arg);
static inline void close_cmd_fd(int h);

static inline void add_poll(int h, int fd, int type, int flags,
                            uint32_t user_id);

static std::recursive_mutex thread_slot_lock;

static inline int create_thread(void* (*start_routine)(void*), void* arg,
                                pthread_t* thread_id) {
  pthread_attr_t thread_attr;
  pthread_attr_init(&thread_attr);
  pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);
  int policy;
  int min_pri = 0;
  int ret = -1;
  struct sched_param param;

  ret = pthread_create(thread_id, &thread_attr, start_routine, arg);
  if (ret != 0) {
    APPL_TRACE_ERROR("pthread_create : %s", strerror(errno));
    return ret;
  }
  /* We need to lower the priority of this thread to ensure the stack gets
   * priority over transfer to a socket */
  pthread_getschedparam(*thread_id, &policy, &param);
  min_pri = sched_get_priority_min(policy);
  if (param.sched_priority > min_pri) {
    param.sched_priority -= 1;
  }
  pthread_setschedparam(*thread_id, policy, &param);
  return ret;
}
static void init_poll(int cmd_fd);
static int alloc_thread_slot() {
  std::unique_lock<std::recursive_mutex> lock(thread_slot_lock);
  int i;
  // reversed order to save guard uninitialized access to 0 index
  for (i = MAX_THREAD - 1; i >= 0; i--) {
    if (!ts[i].used) {
      ts[i].used = 1;
      return i;
    }
  }
  APPL_TRACE_ERROR("execeeded max thread count");
  return -1;
}
static void free_thread_slot(int h) {
  if (0 <= h && h < MAX_THREAD) {
    close_cmd_fd(h);
    ts[h].used = 0;
  } else
    APPL_TRACE_ERROR("invalid thread handle:%d", h);
}
void btsock_thread_init() {
  static int initialized;
  if (!initialized) {
    initialized = 1;
    int h;
    for (h = 0; h < MAX_THREAD; h++) {
      ts[h].cmd_fdr = ts[h].cmd_fdw = -1;
      ts[h].used = 0;
      ts[h].thread_id = std::nullopt;
      ts[h].poll_count = 0;
      ts[h].callback = NULL;
      ts[h].cmd_callback = NULL;
    }
  }
}
int btsock_thread_create(btsock_signaled_cb callback,
                         btsock_cmd_cb cmd_callback) {
  asrt(callback || cmd_callback);
  int h = alloc_thread_slot();
  if (h >= 0) {
    init_poll(h);
    pthread_t thread;
    int status = create_thread(sock_poll_thread, (void*)(uintptr_t)h, &thread);
    if (status) {
      APPL_TRACE_ERROR("create_thread failed: %s", strerror(status));
      free_thread_slot(h);
      return -1;
    }

    ts[h].thread_id = thread;
    ts[h].callback = callback;
    ts[h].cmd_callback = cmd_callback;
  }
  return h;
}

/* create dummy socket pair used to wake up select loop */
static inline void init_cmd_fd(int h) {
  asrt(ts[h].cmd_fdr == -1 && ts[h].cmd_fdw == -1);
  if (socketpair(AF_UNIX, SOCK_STREAM, 0, &ts[h].cmd_fdr) < 0) {
    APPL_TRACE_ERROR("socketpair failed: %s", strerror(errno));
    return;
  }
  // add the cmd fd for read & write
  add_poll(h, ts[h].cmd_fdr, 0, SOCK_THREAD_FD_RD, 0);
}
static inline void close_cmd_fd(int h) {
  if (ts[h].cmd_fdr != -1) {
    close(ts[h].cmd_fdr);
    ts[h].cmd_fdr = -1;
  }
  if (ts[h].cmd_fdw != -1) {
    close(ts[h].cmd_fdw);
    ts[h].cmd_fdw = -1;
  }
}
typedef struct {
  int id;
  int fd;
  int type;
  int flags;
  uint32_t user_id;
} sock_cmd_t;
int btsock_thread_add_fd(int h, int fd, int type, int flags, uint32_t user_id) {
  if (h < 0 || h >= MAX_THREAD) {
    APPL_TRACE_ERROR("invalid bt thread handle:%d", h);
    return false;
  }
  if (ts[h].cmd_fdw == -1) {
    APPL_TRACE_ERROR(
        "cmd socket is not created. socket thread may not initialized");
    return false;
  }
  if (flags & SOCK_THREAD_ADD_FD_SYNC) {
    // must executed in socket poll thread
    if (ts[h].thread_id.value() == pthread_self()) {
      // cleanup one-time flags
      flags &= ~SOCK_THREAD_ADD_FD_SYNC;
      add_poll(h, fd, type, flags, user_id);
      return true;
    }
    LOG_WARN(
        "THREAD_ADD_FD_SYNC is not called in poll thread, fallback to async");
  }
  sock_cmd_t cmd = {CMD_ADD_FD, fd, type, flags, user_id};

  ssize_t ret;
  OSI_NO_INTR(ret = send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0));

  return ret == sizeof(cmd);
}

bool btsock_thread_remove_fd_and_close(int thread_handle, int fd) {
  if (thread_handle < 0 || thread_handle >= MAX_THREAD) {
    APPL_TRACE_ERROR("%s invalid thread handle: %d", __func__, thread_handle);
    return false;
  }
  if (fd == -1) {
    APPL_TRACE_ERROR("%s invalid file descriptor.", __func__);
    return false;
  }

  sock_cmd_t cmd = {CMD_REMOVE_FD, fd, 0, 0, 0};

  ssize_t ret;
  OSI_NO_INTR(ret = send(ts[thread_handle].cmd_fdw, &cmd, sizeof(cmd), 0));

  return ret == sizeof(cmd);
}

int btsock_thread_post_cmd(int h, int type, const unsigned char* data, int size,
                           uint32_t user_id) {
  if (h < 0 || h >= MAX_THREAD) {
    APPL_TRACE_ERROR("invalid bt thread handle:%d", h);
    return false;
  }
  if (ts[h].cmd_fdw == -1) {
    APPL_TRACE_ERROR(
        "cmd socket is not created. socket thread may not initialized");
    return false;
  }
  sock_cmd_t cmd = {CMD_USER_PRIVATE, 0, type, size, user_id};
  sock_cmd_t* cmd_send = &cmd;
  int size_send = sizeof(cmd);
  if (data && size) {
    size_send = sizeof(cmd) + size;
    cmd_send = (sock_cmd_t*)alloca(size_send);
    if (cmd_send) {
      *cmd_send = cmd;
      memcpy(cmd_send + 1, data, size);
    } else {
      APPL_TRACE_ERROR("alloca failed at h:%d, cmd type:%d, size:%d", h, type,
                       size_send);
      return false;
    }
  }

  ssize_t ret;
  OSI_NO_INTR(ret = send(ts[h].cmd_fdw, cmd_send, size_send, 0));

  return ret == size_send;
}
int btsock_thread_wakeup(int h) {
  if (h < 0 || h >= MAX_THREAD) {
    APPL_TRACE_ERROR("invalid bt thread handle:%d", h);
    return false;
  }
  if (ts[h].cmd_fdw == -1) {
    APPL_TRACE_ERROR("thread handle:%d, cmd socket is not created", h);
    return false;
  }
  sock_cmd_t cmd = {CMD_WAKEUP, 0, 0, 0, 0};

  ssize_t ret;
  OSI_NO_INTR(ret = send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0));

  return ret == sizeof(cmd);
}
int btsock_thread_exit(int h) {
  if (h < 0 || h >= MAX_THREAD) {
    APPL_TRACE_ERROR("invalid bt thread slot:%d", h);
    return false;
  }
  if (ts[h].cmd_fdw == -1) {
    APPL_TRACE_ERROR("cmd socket is not created");
    return false;
  }
  sock_cmd_t cmd = {CMD_EXIT, 0, 0, 0, 0};

  ssize_t ret;
  OSI_NO_INTR(ret = send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0));

  if (ret == sizeof(cmd)) {
    if (ts[h].thread_id != std::nullopt) {
      pthread_join(ts[h].thread_id.value(), 0);
      ts[h].thread_id = std::nullopt;
    }
    free_thread_slot(h);
    return true;
  }
  return false;
}
static void init_poll(int h) {
  int i;
  ts[h].poll_count = 0;
  ts[h].thread_id = std::nullopt;
  ts[h].callback = NULL;
  ts[h].cmd_callback = NULL;
  for (i = 0; i < MAX_POLL; i++) {
    ts[h].ps[i].pfd.fd = -1;
    ts[h].psi[i] = -1;
  }
  init_cmd_fd(h);
}
static inline unsigned int flags2pevents(int flags) {
  unsigned int pevents = 0;
  if (flags & SOCK_THREAD_FD_WR) pevents |= POLLOUT;
  if (flags & SOCK_THREAD_FD_RD) pevents |= POLLIN;
  pevents |= POLL_EXCEPTION_EVENTS;
  return pevents;
}

static inline void set_poll(poll_slot_t* ps, int fd, int type, int flags,
                            uint32_t user_id) {
  ps->pfd.fd = fd;
  ps->user_id = user_id;
  if (ps->type != 0 && ps->type != type)
    APPL_TRACE_ERROR(
        "poll socket type should not changed! type was:%d, type now:%d",
        ps->type, type);
  ps->type = type;
  ps->flags = flags;
  ps->pfd.events = flags2pevents(flags);
  ps->pfd.revents = 0;
}
static inline void add_poll(int h, int fd, int type, int flags,
                            uint32_t user_id) {
  asrt(fd != -1);
  int i;
  int empty = -1;
  poll_slot_t* ps = ts[h].ps;

  for (i = 0; i < MAX_POLL; i++) {
    if (ps[i].pfd.fd == fd) {
      asrt(ts[h].poll_count < MAX_POLL);

      set_poll(&ps[i], fd, type, flags | ps[i].flags, user_id);
      return;
    } else if (empty < 0 && ps[i].pfd.fd == -1)
      empty = i;
  }
  if (empty >= 0) {
    asrt(ts[h].poll_count < MAX_POLL);
    set_poll(&ps[empty], fd, type, flags, user_id);
    ++ts[h].poll_count;
    return;
  }
  APPL_TRACE_ERROR("exceeded max poll slot:%d!", MAX_POLL);
}
static inline void remove_poll(int h, poll_slot_t* ps, int flags) {
  if (flags == ps->flags) {
    // all monitored events signaled. To remove it, just clear the slot
    --ts[h].poll_count;
    memset(ps, 0, sizeof(*ps));
    ps->pfd.fd = -1;
  } else {
    // one read or one write monitor event signaled, removed the accordding bit
    ps->flags &= ~flags;
    // update the poll events mask
    ps->pfd.events = flags2pevents(ps->flags);
  }
}
static int process_cmd_sock(int h) {
  sock_cmd_t cmd = {-1, 0, 0, 0, 0};
  int fd = ts[h].cmd_fdr;

  ssize_t ret;
  OSI_NO_INTR(ret = recv(fd, &cmd, sizeof(cmd), MSG_WAITALL));

  if (ret != sizeof(cmd)) {
    LOG_ERROR("recv cmd errno:%d", errno);
    return false;
  }
  switch (cmd.id) {
    case CMD_ADD_FD:
      add_poll(h, cmd.fd, cmd.type, cmd.flags, cmd.user_id);
      break;
    case CMD_REMOVE_FD:
      for (int i = 1; i < MAX_POLL; ++i) {
        poll_slot_t* poll_slot = &ts[h].ps[i];
        if (poll_slot->pfd.fd == cmd.fd) {
          remove_poll(h, poll_slot, poll_slot->flags);
          break;
        }
      }
      close(cmd.fd);
      break;
    case CMD_WAKEUP:
      break;
    case CMD_USER_PRIVATE:
      asrt(ts[h].cmd_callback);
      if (ts[h].cmd_callback)
        ts[h].cmd_callback(fd, cmd.type, cmd.flags, cmd.user_id);
      break;
    case CMD_EXIT:
      return false;
    default:
      LOG_WARN("unknown cmd: %d", cmd.id);
      break;
  }
  return true;
}

static void process_data_sock(int h, struct pollfd* pfds, int count) {
  asrt(count <= ts[h].poll_count);
  int i;
  for (i = 1; i < ts[h].poll_count; i++) {
    if (pfds[i].revents) {
      int ps_i = ts[h].psi[i];
      asrt(pfds[i].fd == ts[h].ps[ps_i].pfd.fd);
      uint32_t user_id = ts[h].ps[ps_i].user_id;
      int type = ts[h].ps[ps_i].type;
      int flags = 0;
      if (IS_READ(pfds[i].revents)) {
        flags |= SOCK_THREAD_FD_RD;
      }
      if (IS_WRITE(pfds[i].revents)) {
        flags |= SOCK_THREAD_FD_WR;
      }
      if (IS_EXCEPTION(pfds[i].revents)) {
        flags |= SOCK_THREAD_FD_EXCEPTION;
        // remove the whole slot not flags
        remove_poll(h, &ts[h].ps[ps_i], ts[h].ps[ps_i].flags);
      } else if (flags)
        remove_poll(h, &ts[h].ps[ps_i],
                    flags);  // remove the monitor flags that already processed
      if (flags) ts[h].callback(pfds[i].fd, type, flags, user_id);
    }
  }
}

static void prepare_poll_fds(int h, struct pollfd* pfds) {
  int count = 0;
  int ps_i = 0;
  int pfd_i = 0;
  asrt(ts[h].poll_count <= MAX_POLL);
  memset(pfds, 0, sizeof(pfds[0]) * ts[h].poll_count);
  while (count < ts[h].poll_count) {
    if (ps_i >= MAX_POLL) {
      APPL_TRACE_ERROR(
          "exceed max poll range, ps_i:%d, MAX_POLL:%d, count:%d, "
          "ts[h].poll_count:%d",
          ps_i, MAX_POLL, count, ts[h].poll_count);
      return;
    }
    if (ts[h].ps[ps_i].pfd.fd >= 0) {
      pfds[pfd_i] = ts[h].ps[ps_i].pfd;
      ts[h].psi[pfd_i] = ps_i;
      count++;
      pfd_i++;
    }
    ps_i++;
  }
}
static void* sock_poll_thread(void* arg) {
  struct pollfd pfds[MAX_POLL];
  memset(pfds, 0, sizeof(pfds));
  int h = (intptr_t)arg;
  for (;;) {
    prepare_poll_fds(h, pfds);
    int ret;
    OSI_NO_INTR(ret = poll(pfds, ts[h].poll_count, -1));
    if (ret == -1) {
      APPL_TRACE_ERROR("poll ret -1, exit the thread, errno:%d, err:%s", errno,
                       strerror(errno));
      break;
    }
    if (ret != 0) {
      int need_process_data_fd = true;
      if (pfds[0].revents)  // cmd fd always is the first one
      {
        asrt(pfds[0].fd == ts[h].cmd_fdr);
        if (!process_cmd_sock(h)) {
          LOG_INFO("h:%d, process_cmd_sock return false, exit...", h);
          break;
        }
        if (ret == 1)
          need_process_data_fd = false;
        else
          ret--;  // exclude the cmd fd
      }
      if (need_process_data_fd) process_data_sock(h, pfds, ret);
    } else {
      LOG_INFO("no data, select ret: %d", ret);
    };
  }
  LOG_INFO("socket poll thread exiting, h:%d", h);
  return 0;
}
