/** @file

  A brief file description

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.
 */

#include "tscore/ink_config.h"
#include "tscore/ink_defs.h"
#include "tscore/ink_sock.h"
#include "tscore/ink_string.h"
#include "tscore/ink_memory.h"
#include "tscore/I_Layout.h"
#include "NetworkUtilsRemote.h"
#include "CoreAPI.h"
#include "CoreAPIShared.h"
#include "MgmtSocket.h"
#include "MgmtMarshall.h"

CallbackTable *remote_event_callbacks;

int main_socket_fd  = -1;
int event_socket_fd = -1;

// need to store for reconnecting scenario
char *main_socket_path  = nullptr; // "<path>/mgmtapi.sock"
char *event_socket_path = nullptr; // "<path>/eventapi.sock"

static void *event_callback_thread(void *arg);

/**********************************************************************
 * Socket Helper Functions
 **********************************************************************/
void
set_socket_paths(const char *path)
{
  // free previously set paths if needed
  ats_free(main_socket_path);
  ats_free(event_socket_path);

  // construct paths based on user input
  // form by replacing "mgmtapi.sock" with "eventapi.sock"
  if (path) {
    main_socket_path  = ats_stringdup(Layout::relative_to(path, MGMTAPI_MGMT_SOCKET_NAME));
    event_socket_path = ats_stringdup(Layout::relative_to(path, MGMTAPI_EVENT_SOCKET_NAME));
  } else {
    main_socket_path  = nullptr;
    event_socket_path = nullptr;
  }

  return;
}

/**********************************************************************
 * socket_test
 *
 * purpose: performs socket write to check status of other end of connection
 * input: None
 * output: return false if socket write failed due to some other error
 *         return true if socket write successful
 * notes: send the API_PING test msg
 **********************************************************************/
static bool
socket_test(int fd)
{
  OpType optype       = OpType::API_PING;
  MgmtMarshallInt now = time(nullptr);

  if (MGMTAPI_SEND_MESSAGE(fd, OpType::API_PING, &optype, &now) == TS_ERR_OKAY) {
    return true; // write was successful; connection still open
  }

  return false;
}

/***************************************************************************
 * connect
 *
 * purpose: connects to the port on traffic server that listens to mgmt
 *          requests & issues out responses and alerts
 * 1) create and set the client socket_fd; connect to TM
 * 2) create and set the client's event_socket_fd; connect to TM
 * output: TS_ERR_OKAY          - if both sockets successfully connect to TM
 *         TS_ERR_NET_ESTABLISH - at least one unsuccessful connection
 * notes: If connection breaks it is responsibility of client to reconnect
 *        otherwise traffic server will assume mgmt stopped request and
 *        goes back to just sitting and listening for connection.
 ***************************************************************************/
TSMgmtError
ts_connect()
{
  struct sockaddr_un client_sock;
  struct sockaddr_un client_event_sock;

  int sockaddr_len;

  // make sure a socket path is set up
  if (!main_socket_path || !event_socket_path) {
    goto ERROR;
  }
  // make sure the length of main_socket_path do not exceed the sizeof(sun_path)
  if (strlen(main_socket_path) > sizeof(client_sock.sun_path) - 1) {
    goto ERROR;
  }
  // make sure the length of event_socket_path do not exceed the sizeof(sun_path)
  if (strlen(event_socket_path) > sizeof(client_event_sock.sun_path) - 1) {
    goto ERROR;
  }
  // create a socket
  main_socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
  if (main_socket_fd < 0) {
    goto ERROR; // ERROR - can't open socket
  }
  // setup Unix domain socket
  memset(&client_sock, 0, sizeof(sockaddr_un));
  client_sock.sun_family = AF_UNIX;
  ink_strlcpy(client_sock.sun_path, main_socket_path, sizeof(client_sock.sun_path));
#if defined(darwin) || defined(freebsd)
  sockaddr_len = sizeof(sockaddr_un);
#else
  sockaddr_len = sizeof(client_sock.sun_family) + strlen(client_sock.sun_path);
#endif
  // connect call
  if (connect(main_socket_fd, reinterpret_cast<struct sockaddr *>(&client_sock), sockaddr_len) < 0) {
    close(main_socket_fd);
    main_socket_fd = -1;
    goto ERROR; // connection is down
  }
  // -------- set up the event socket ------------------
  // create a socket
  event_socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
  if (event_socket_fd < 0) {
    close(main_socket_fd); // close the other socket too!
    main_socket_fd = -1;
    goto ERROR; // ERROR - can't open socket
  }
  // setup Unix domain socket
  memset(&client_event_sock, 0, sizeof(sockaddr_un));
  client_event_sock.sun_family = AF_UNIX;
  ink_strlcpy(client_event_sock.sun_path, event_socket_path, sizeof(client_event_sock.sun_path));
#if defined(darwin) || defined(freebsd)
  sockaddr_len = sizeof(sockaddr_un);
#else
  sockaddr_len = sizeof(client_event_sock.sun_family) + strlen(client_event_sock.sun_path);
#endif
  // connect call
  if (connect(event_socket_fd, reinterpret_cast<struct sockaddr *>(&client_event_sock), sockaddr_len) < 0) {
    close(event_socket_fd);
    close(main_socket_fd);
    event_socket_fd = -1;
    main_socket_fd  = -1;
    goto ERROR; // connection is down
  }

  return TS_ERR_OKAY;

ERROR:
  return TS_ERR_NET_ESTABLISH;
}

/***************************************************************************
 * disconnect
 *
 * purpose: disconnect from traffic server; closes sockets and resets their values
 * input: None
 * output: TS_ERR_FAIL, TS_ERR_OKAY
 * notes: doesn't do clean up - all cleanup should be done before here
 ***************************************************************************/
TSMgmtError
disconnect()
{
  int ret;

  if (main_socket_fd > 0) {
    ret            = close(main_socket_fd);
    main_socket_fd = -1;
    if (ret < 0) {
      return TS_ERR_FAIL;
    }
  }

  if (event_socket_fd > 0) {
    ret             = close(event_socket_fd);
    event_socket_fd = -1;
    if (ret < 0) {
      return TS_ERR_FAIL;
    }
  }

  return TS_ERR_OKAY;
}

/***************************************************************************
 * reconnect
 *
 * purpose: reconnects to TM (eg. when TM restarts); does all the necessary
 *          set up for reconnection
 * input: None
 * output: TS_ERR_FAIL, TS_ERR_OKAY
 * notes: necessary events for a new client-TM connection:
 * 1) get new socket_fd using old socket_path by calling connect()
 * 2) relaunch event_poll_thread_main with new socket_fd
 * 3) re-notify TM of all the client's registered callbacks by send msg
 ***************************************************************************/
TSMgmtError
reconnect()
{
  TSMgmtError err;

  err = disconnect();
  if (err != TS_ERR_OKAY) { // problem disconnecting
    return err;
  }

  // use the socket_path that was called by remote client on first init
  // use connect instead of TSInit() b/c if TM restarted, client-side tables
  // would be recreated; just want to reconnect to same socket_path
  err = ts_connect();
  if (err != TS_ERR_OKAY) { // problem establishing connection
    return err;
  }

  // relaunch a new event thread since socket_fd changed
  if (0 == (ts_init_options & TS_MGMT_OPT_NO_EVENTS)) {
    ink_thread_create(&ts_event_thread, event_poll_thread_main, &event_socket_fd, 0, 0, nullptr);
    // re-register the callbacks on the TM side for this new client connection
    if (remote_event_callbacks) {
      err = send_register_all_callbacks(event_socket_fd, remote_event_callbacks);
      if (err != TS_ERR_OKAY) { // problem establishing connection
        return err;
      }
    }
  } else {
    ts_event_thread = ink_thread_null();
  }

  return TS_ERR_OKAY;
}

/***************************************************************************
 * reconnect_loop
 *
 * purpose: attempts to reconnect to TM (eg. when TM restarts) for the
 *          specified number of times
 * input:  num_attempts - number of reconnection attempts to try before quit
 * output: TS_ERR_OKAY - if successfully reconnected within num_attempts
 *         TS_ERR_xx - the reason the reconnection failed
 * notes:
 ***************************************************************************/
TSMgmtError
reconnect_loop(int num_attempts)
{
  int numTries    = 0;
  TSMgmtError err = TS_ERR_FAIL;

  while (numTries < num_attempts) {
    numTries++;
    err = reconnect();
    if (err == TS_ERR_OKAY) {
      return TS_ERR_OKAY; // successful connection
    }
    sleep(1); // to make it slower
  }

  return err; // unsuccessful connection after num_attempts
}

/*************************************************************************
 * connect_and_send
 *
 * purpose:
 * When sending a request, it's possible that the user had restarted
 * Traffic Manager. This means that the connection between TM and
 * the remote client has been broken, so the client needs to re-"connect"
 * to Traffic Manager. So, after "writing" to the socket in each
 * "send_xx_request" function, need to check if the TM socket has
 * been closed or not; the "write" function's errno will indicate if
 * the other end of the socket has been closed or not. If it is closed,
 * then need to try to re"connect", then resend the message request if
 * the "connect" was successful.
 * 1) try connect()
 * 2) if connect() success, then resend the request.
 * output: TS_ERR_NET_xx - connection problem or TS_ERR_OKAY
 * notes:
 * This function is basically called by the special "socket_write_conn" fn
 * which will call this fn if it tries to write to the socket and discovers
 * the local end of the socket is closed
 * Warning: system also sends a SIGPIPE error when try to write to socket
 * which is not open; which will by default terminate the process;
 * client needs to "ignore" the SIGPIPE signal
 **************************************************************************/
static TSMgmtError
main_socket_reconnect()
{
  TSMgmtError err;

  // connects to TM and does all necessary event updates required
  err = reconnect();
  if (err != TS_ERR_OKAY) {
    return err;
  }

  // makes sure the descriptor is writable
  if (mgmt_write_timeout(main_socket_fd, MAX_TIME_WAIT, 0) <= 0) {
    return TS_ERR_NET_TIMEOUT;
  }

  return TS_ERR_OKAY;
}

static TSMgmtError
socket_write_conn(int fd, const void *msg_buf, size_t bytes)
{
  size_t byte_wrote = 0;

  // makes sure the descriptor is writable
  if (mgmt_write_timeout(fd, MAX_TIME_WAIT, 0) <= 0) {
    return TS_ERR_NET_TIMEOUT;
  }

  // write until we fulfill the number
  while (byte_wrote < bytes) {
    ssize_t ret = write(fd, static_cast<const char *>(msg_buf) + byte_wrote, bytes - byte_wrote);

    if (ret == 0) {
      return TS_ERR_NET_EOF;
    }

    if (ret < 0) {
      if (mgmt_transient_error()) {
        continue;
      } else {
        return TS_ERR_NET_WRITE;
      }
    }

    // we are all good here
    byte_wrote += ret;
  }

  return TS_ERR_OKAY;
}

TSMgmtError
mgmtapi_sender::send(void *msg, size_t msglen) const
{
  const unsigned tries = 5;
  TSMgmtError err;

  for (unsigned i = 0; i < tries; ++i) {
    err = socket_write_conn(this->fd, msg, msglen);
    if (err == TS_ERR_OKAY) {
      return err;
    }

    // clean-up sockets
    close(main_socket_fd);
    close(event_socket_fd);
    main_socket_fd  = -1;
    event_socket_fd = -1;

    err = main_socket_reconnect();
    if (err != TS_ERR_OKAY) {
      return err;
    }
  }

  return TS_ERR_NET_ESTABLISH; // can't establish connection
}

/**********************************************************************
 * socket_test_thread
 *
 * purpose: continually polls to check if local end of socket connection
 *          is still open; this thread is created when the client calls
 *          Init() to initialize the API; and will not
 *          die until the client process dies
 * input: none
 * output: if other end is closed, it reconnects to TM
 * notes: uses the current main_socket_fd because the main_socket_fd could be
 *        in flux; basically it is possible that the client will reconnect
 *        from some other call, thus making the main_socket_fd actually
 *        valid when socket_test is called
 * reason: decided to create this "watcher" thread for the socket
 *         connection because if TM is restarted or the client process
 *         is started before the TM process, then the client will not
 *         be able to receive any event notifications until a "request"
 *         is issued. In order to prevent losing an event notifications
 *         that are called in between the time TM is restarted and
 *         client issues a first request, we just run this thread which
 *         will try to reconnect to TM if it is not already connected
 **********************************************************************/
void *
socket_test_thread(void *)
{
  // loop until client process dies
  while (true) {
    if (main_socket_fd == -1 || !socket_test(main_socket_fd)) {
      // ASSUMES that in between the time the socket_test is made
      // and this reconnect call is made, the main_socket_fd remains
      // the same (eg. no one else called reconnect to TM successfully!!
      // WHAT IF in between this time, the client had issued a request
      // calling socket_write_conn which then calls reconnect(); then
      // reconnect will return an "ALREADY CONNECTED" error when it
      // tries to connect, and on the next loop iteration, the socket_test
      // will actually pass because main_socket_fd is valid!!
      reconnect();
    }

    sleep(5);
  }

  ink_thread_exit(nullptr);
  return nullptr;
}

/**********************************************************************
 * MARSHALL REQUESTS
 **********************************************************************/

/*------ events -------------------------------------------------------*/

/**********************************************************************
 * send_register_all_callbacks
 *
 * purpose: determines all events which have at least one callback registered
 *          and sends message to notify TM that this client has a callback
 *          registered for each event
 * input: None
 * output: return TS_ERR_OKAY only if ALL events sent okay
 * 1) get list of all events with callbacks
 * 2) for each event, send a EVENT_REG_CALLBACK message
 **********************************************************************/
TSMgmtError
send_register_all_callbacks(int fd, CallbackTable *cb_table)
{
  LLQ *events_with_cb;
  TSMgmtError err, send_err = TS_ERR_FAIL;
  bool no_errors = true; // set to false if one send is not okay

  events_with_cb = get_events_with_callbacks(cb_table);
  // need to check that the list has all the events registered
  if (!events_with_cb) { // all events have registered callback
    OpType optype                 = OpType::EVENT_REG_CALLBACK;
    MgmtMarshallString event_name = nullptr;

    err = MGMTAPI_SEND_MESSAGE(fd, OpType::EVENT_REG_CALLBACK, &optype, &event_name);
    if (err != TS_ERR_OKAY) {
      return err;
    }
  } else {
    int num_events = queue_len(events_with_cb);
    // iterate through the LLQ and send request for each event
    for (int i = 0; i < num_events; i++) {
      OpType optype                 = OpType::EVENT_REG_CALLBACK;
      MgmtMarshallInt event_id      = *static_cast<int *>(dequeue(events_with_cb));
      MgmtMarshallString event_name = get_event_name(event_id);

      if (event_name) {
        err = MGMTAPI_SEND_MESSAGE(fd, OpType::EVENT_REG_CALLBACK, &optype, &event_name);
        ats_free(event_name); // free memory
        if (err != TS_ERR_OKAY) {
          send_err  = err; // save the type of send error
          no_errors = false;
        }
      }
      // REMEMBER: WON"T GET A REPLY from TM side!
    }
  }

  if (events_with_cb) {
    delete_queue(events_with_cb);
  }

  if (no_errors) {
    return TS_ERR_OKAY;
  } else {
    return send_err;
  }
}

/**********************************************************************
 * send_unregister_all_callbacks
 *
 * purpose: determines all events which have no callback registered
 *          and sends message to notify TM that this client has no
 *          callbacks registered for that event
 * input: None
 * output: TS_ERR_OKAY only if all send requests are okay
 **********************************************************************/
TSMgmtError
send_unregister_all_callbacks(int fd, CallbackTable *cb_table)
{
  LLQ *events_with_cb; // list of events with at least one callback
  int reg_callback[NUM_EVENTS];
  TSMgmtError err, send_err = TS_ERR_FAIL;
  bool no_errors = true; // set to false if at least one send fails

  // init array so that all events don't have any callbacks
  for (int &i : reg_callback) {
    i = 0;
  }

  events_with_cb = get_events_with_callbacks(cb_table);
  if (!events_with_cb) { // all events have a registered callback
    return TS_ERR_OKAY;
  } else {
    int num_events = queue_len(events_with_cb);
    // iterate through the LLQ and mark events that have a callback
    for (int i = 0; i < num_events; i++) {
      int event_id           = *static_cast<int *>(dequeue(events_with_cb));
      reg_callback[event_id] = 1; // mark the event as having a callback
    }
    delete_queue(events_with_cb);
  }

  // send message to TM to mark unregister
  for (int k = 0; k < NUM_EVENTS; k++) {
    if (reg_callback[k] == 0) { // event has no registered callbacks
      OpType optype                 = OpType::EVENT_UNREG_CALLBACK;
      MgmtMarshallString event_name = get_event_name(k);

      err = MGMTAPI_SEND_MESSAGE(fd, OpType::EVENT_UNREG_CALLBACK, &optype, &event_name);
      ats_free(event_name);
      if (err != TS_ERR_OKAY) {
        send_err  = err; // save the type of the sending error
        no_errors = false;
      }
      // REMEMBER: WON"T GET A REPLY!
      // only the event_poll_thread_main does any reading of the event_socket;
      // so DO NOT parse reply b/c a reply won't be sent
    }
  }

  if (no_errors) {
    return TS_ERR_OKAY;
  } else {
    return send_err;
  }
}

/**********************************************************************
 * UNMARSHAL REPLIES
 **********************************************************************/

TSMgmtError
parse_generic_response(OpType optype, int fd)
{
  TSMgmtError err;
  MgmtMarshallInt ival;
  MgmtMarshallData data = {nullptr, 0};

  err = recv_mgmt_message(fd, data);
  if (err != TS_ERR_OKAY) {
    return err;
  }

  err = recv_mgmt_response(data.ptr, data.len, optype, &ival);
  ats_free(data.ptr);

  if (err != TS_ERR_OKAY) {
    return err;
  }

  return static_cast<TSMgmtError>(ival);
}

/**********************************************************************
 * event_poll_thread_main
 *
 * purpose: thread listens on the client's event socket connection;
 *          only reads from the event_socket connection and
 *          processes EVENT_NOTIFY messages; each time client
 *          makes new event-socket connection to TM, must launch
 *          a new event_poll_thread_main thread
 * input:   arg - contains the socket_fd to listen on
 * output:  NULL - if error
 * notes:   each time the client's socket connection to TM is reset
 *          a new thread will be launched as old one dies; there are
 *          only two places where a new thread is created:
 *          1) when client first connects (TSInit call)
 *          2) client reconnects() due to a TM restart
 * Uses blocking socket; so blocks until receives an event notification.
 * Shouldn't need to use select since only waiting for a notification
 * message from event_callback_main thread!
 **********************************************************************/
void *
event_poll_thread_main(void *arg)
{
  int sock_fd;

  sock_fd = *(static_cast<int *>(arg)); // should be same as event_socket_fd

  // the sock_fd is going to be the one we listen for events on
  while (true) {
    TSMgmtError ret;
    TSMgmtEvent *event = nullptr;

    MgmtMarshallData reply = {nullptr, 0};
    OpType optype;
    MgmtMarshallString name = nullptr;
    MgmtMarshallString desc = nullptr;

    // possible sock_fd is invalid if TM restarts and client reconnects
    if (sock_fd < 0) {
      break;
    }

    // Just wait until we get an event or error. The 0 return from select(2)
    // means we timed out ...
    if (mgmt_read_timeout(main_socket_fd, MAX_TIME_WAIT, 0) == 0) {
      continue;
    }

    ret = recv_mgmt_message(main_socket_fd, reply);
    if (ret != TS_ERR_OKAY) {
      break;
    }

    ret = recv_mgmt_request(reply.ptr, reply.len, OpType::EVENT_NOTIFY, &optype, &name, &desc);
    ats_free(reply.ptr);

    if (ret != TS_ERR_OKAY) {
      ats_free(name);
      ats_free(desc);
      break;
    }

    ink_assert(optype == OpType::EVENT_NOTIFY);

    // The new event takes ownership of the message strings.
    event              = TSEventCreate();
    event->name        = name;
    event->id          = get_event_id(name);
    event->description = desc;

    // got event notice; spawn new thread to handle the event's callback functions
    ink_thread_create(nullptr, event_callback_thread, (void *)event, 0, 0, nullptr);
  }

  ink_thread_exit(nullptr);
  return nullptr;
}

/**********************************************************************
 * event_callback_thread
 *
 * purpose: Given an event, determines and calls the registered cb functions
 *          in the CallbackTable for remote events
 * input: arg - should be an TSMgmtEvent with the event info sent from TM msg
 * output: returns when done calling all the callbacks
 * notes: None
 **********************************************************************/
static void *
event_callback_thread(void *arg)
{
  TSMgmtEvent *event_notice;
  EventCallbackT *event_cb;
  int index;

  event_notice = static_cast<TSMgmtEvent *>(arg);
  index        = event_notice->id;
  LLQ *func_q; // list of callback functions need to call

  func_q = create_queue();
  if (!func_q) {
    TSEventDestroy(event_notice);
    return nullptr;
  }

  // obtain lock
  ink_mutex_acquire(&remote_event_callbacks->event_callback_lock);

  TSEventSignalFunc cb;

  // check if we have functions to call
  if (remote_event_callbacks->event_callback_l[index] && (!queue_is_empty(remote_event_callbacks->event_callback_l[index]))) {
    int queue_depth = queue_len(remote_event_callbacks->event_callback_l[index]);

    for (int i = 0; i < queue_depth; i++) {
      event_cb = static_cast<EventCallbackT *>(dequeue(remote_event_callbacks->event_callback_l[index]));
      cb       = event_cb->func;
      enqueue(remote_event_callbacks->event_callback_l[index], event_cb);
      enqueue(func_q, reinterpret_cast<void *>(cb)); // add callback function only to list
    }
  }
  // release lock
  ink_mutex_release(&remote_event_callbacks->event_callback_lock);

  // execute the callback function
  while (!queue_is_empty(func_q)) {
    cb = reinterpret_cast<TSEventSignalFunc>(dequeue(func_q));
    (*cb)(event_notice->name, event_notice->description, event_notice->priority, nullptr);
  }

  // clean up event notice
  TSEventDestroy(event_notice);
  delete_queue(func_q);

  // all done!
  ink_thread_exit(nullptr);
  return nullptr;
}
