/** @file

  Network message marshalling.

  @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_error.h"
#include "tscore/ink_assert.h"
#include "tscore/ink_memory.h"
#include "mgmtapi.h"
#include "NetworkMessage.h"

#define MAX_OPERATION_FIELDS 16

struct NetCmdOperation {
  unsigned nfields;
  const MgmtMarshallType fields[MAX_OPERATION_FIELDS];
};

// Requests always begin with a OpType, followed by additional fields.
static const struct NetCmdOperation requests[] = {
  /* RECORD_SET                 */ {3, {MGMT_MARSHALL_INT, MGMT_MARSHALL_STRING, MGMT_MARSHALL_STRING}},
  /* RECORD_GET                 */ {2, {MGMT_MARSHALL_INT, MGMT_MARSHALL_STRING}},
  /* PROXY_STATE_GET            */ {1, {MGMT_MARSHALL_INT}},
  /* PROXY_STATE_SET            */ {3, {MGMT_MARSHALL_INT, MGMT_MARSHALL_INT, MGMT_MARSHALL_INT}},
  /* RECONFIGURE                */ {1, {MGMT_MARSHALL_INT}},
  /* RESTART                    */ {2, {MGMT_MARSHALL_INT, MGMT_MARSHALL_INT}},
  /* BOUNCE                     */ {2, {MGMT_MARSHALL_INT, MGMT_MARSHALL_INT}},
  /* STOP                       */ {2, {MGMT_MARSHALL_INT, MGMT_MARSHALL_INT}},
  /* DRAIN                      */ {2, {MGMT_MARSHALL_INT, MGMT_MARSHALL_INT}},
  /* EVENT_RESOLVE              */ {2, {MGMT_MARSHALL_INT, MGMT_MARSHALL_STRING}},
  /* EVENT_GET_MLT              */ {1, {MGMT_MARSHALL_INT}},
  /* EVENT_ACTIVE               */ {2, {MGMT_MARSHALL_INT, MGMT_MARSHALL_STRING}},
  /* EVENT_REG_CALLBACK         */ {2, {MGMT_MARSHALL_INT, MGMT_MARSHALL_STRING}},
  /* EVENT_UNREG_CALLBACK       */ {2, {MGMT_MARSHALL_INT, MGMT_MARSHALL_STRING}},
  /* EVENT_NOTIFY               */ {3, {MGMT_MARSHALL_INT, MGMT_MARSHALL_STRING, MGMT_MARSHALL_STRING}}, // only msg sent from TM to
                                                                                                         // client
  /* STATS_RESET_NODE           */ {2, {MGMT_MARSHALL_INT, MGMT_MARSHALL_STRING}},
  /* STORAGE_DEVICE_CMD_OFFLINE */ {2, {MGMT_MARSHALL_INT, MGMT_MARSHALL_STRING}},
  /* RECORD_MATCH_GET           */ {2, {MGMT_MARSHALL_INT, MGMT_MARSHALL_STRING}},
  /* API_PING                   */ {2, {MGMT_MARSHALL_INT, MGMT_MARSHALL_INT}},
  /* SERVER_BACKTRACE           */ {2, {MGMT_MARSHALL_INT, MGMT_MARSHALL_INT}},
  /* RECORD_DESCRIBE_CONFIG     */ {3, {MGMT_MARSHALL_INT, MGMT_MARSHALL_STRING, MGMT_MARSHALL_INT}},
  /* LIFECYCLE_MESSAGE          */ {3, {MGMT_MARSHALL_INT, MGMT_MARSHALL_STRING, MGMT_MARSHALL_DATA}},
  /* HOST_STATUS_HOST_UP        */ {4, {MGMT_MARSHALL_INT, MGMT_MARSHALL_STRING, MGMT_MARSHALL_STRING, MGMT_MARSHALL_INT}},
  /* HOST_STATUS_HOST_DOWN      */ {4, {MGMT_MARSHALL_INT, MGMT_MARSHALL_STRING, MGMT_MARSHALL_STRING, MGMT_MARSHALL_INT}},
};

// Responses always begin with a TSMgmtError code, followed by additional fields.
static const struct NetCmdOperation responses[] = {
  /* RECORD_SET                 */ {2, {MGMT_MARSHALL_INT, MGMT_MARSHALL_INT}},
  /* RECORD_GET                 */
  {5, {MGMT_MARSHALL_INT, MGMT_MARSHALL_INT, MGMT_MARSHALL_INT, MGMT_MARSHALL_STRING, MGMT_MARSHALL_DATA}},
  /* PROXY_STATE_GET            */ {2, {MGMT_MARSHALL_INT, MGMT_MARSHALL_INT}},
  /* PROXY_STATE_SET            */ {1, {MGMT_MARSHALL_INT}},
  /* RECONFIGURE                */ {1, {MGMT_MARSHALL_INT}},
  /* RESTART                    */ {1, {MGMT_MARSHALL_INT}},
  /* BOUNCE                     */ {1, {MGMT_MARSHALL_INT}},
  /* STOP                       */ {1, {MGMT_MARSHALL_INT}},
  /* DRAIN                      */ {1, {MGMT_MARSHALL_INT}},
  /* EVENT_RESOLVE              */ {1, {MGMT_MARSHALL_INT}},
  /* EVENT_GET_MLT              */ {2, {MGMT_MARSHALL_INT, MGMT_MARSHALL_STRING}},
  /* EVENT_ACTIVE               */ {2, {MGMT_MARSHALL_INT, MGMT_MARSHALL_INT}},
  /* EVENT_REG_CALLBACK         */ {0, {}}, // no reply
  /* EVENT_UNREG_CALLBACK       */ {0, {}}, // no reply
  /* EVENT_NOTIFY               */ {0, {}}, // no reply
  /* STATS_RESET_NODE           */ {1, {MGMT_MARSHALL_INT}},
  /* STORAGE_DEVICE_CMD_OFFLINE */ {1, {MGMT_MARSHALL_INT}},
  /* RECORD_MATCH_GET           */
  {5, {MGMT_MARSHALL_INT, MGMT_MARSHALL_INT, MGMT_MARSHALL_INT, MGMT_MARSHALL_STRING, MGMT_MARSHALL_DATA}},
  /* API_PING                   */ {0, {}}, // no reply
  /* SERVER_BACKTRACE           */ {2, {MGMT_MARSHALL_INT, MGMT_MARSHALL_STRING}},
  /* RECORD_DESCRIBE_CONFIG     */
  {15,
   {MGMT_MARSHALL_INT /* status */, MGMT_MARSHALL_STRING /* name */, MGMT_MARSHALL_DATA /* value */,
    MGMT_MARSHALL_DATA /* default */, MGMT_MARSHALL_INT /* type */, MGMT_MARSHALL_INT /* class */, MGMT_MARSHALL_INT /* version */,
    MGMT_MARSHALL_INT /* rsb */, MGMT_MARSHALL_INT /* order */, MGMT_MARSHALL_INT /* access */, MGMT_MARSHALL_INT /* update */,
    MGMT_MARSHALL_INT /* updatetype */, MGMT_MARSHALL_INT /* checktype */, MGMT_MARSHALL_INT /* source */,
    MGMT_MARSHALL_STRING /* checkexpr */}},
  /* LIFECYCLE_MESSAGE          */ {1, {MGMT_MARSHALL_INT}},
  /* HOST_STATUS_UP             */ {1, {MGMT_MARSHALL_INT}},
  /* HOST_STATUS_DOWN           */ {1, {MGMT_MARSHALL_INT}},
};

#define GETCMD(ops, optype, cmd)                           \
  do {                                                     \
    if (static_cast<unsigned>(optype) >= countof(ops)) {   \
      return TS_ERR_PARAMS;                                \
    }                                                      \
    if (ops[static_cast<unsigned>(optype)].nfields == 0) { \
      return TS_ERR_PARAMS;                                \
    }                                                      \
    cmd = &ops[static_cast<unsigned>(optype)];             \
  } while (0);

TSMgmtError
send_mgmt_request(const mgmt_message_sender &snd, OpType optype, ...)
{
  va_list ap;
  ats_scoped_mem<char> msgbuf;
  MgmtMarshallInt msglen;
  const MgmtMarshallType lenfield[] = {MGMT_MARSHALL_INT};
  const NetCmdOperation *cmd;

  if (!snd.is_connected()) {
    return TS_ERR_NET_ESTABLISH; // no connection.
  }

  GETCMD(requests, optype, cmd);

  va_start(ap, optype);
  msglen = mgmt_message_length_v(cmd->fields, cmd->nfields, ap);
  va_end(ap);

  msgbuf = static_cast<char *>(ats_malloc(msglen + 4));

  // First marshall the total message length.
  mgmt_message_marshall((char *)msgbuf, msglen, lenfield, countof(lenfield), &msglen);

  // Now marshall the message itself.
  va_start(ap, optype);
  if (mgmt_message_marshall_v((char *)msgbuf + 4, msglen, cmd->fields, cmd->nfields, ap) == -1) {
    va_end(ap);
    return TS_ERR_PARAMS;
  }

  va_end(ap);
  return snd.send(msgbuf, msglen + 4);
}

TSMgmtError
send_mgmt_request(int fd, OpType optype, ...)
{
  va_list ap;
  MgmtMarshallInt msglen;
  MgmtMarshallData req            = {nullptr, 0};
  const MgmtMarshallType fields[] = {MGMT_MARSHALL_DATA};
  const NetCmdOperation *cmd;

  GETCMD(requests, optype, cmd);

  // Figure out the payload length.
  va_start(ap, optype);
  msglen = mgmt_message_length_v(cmd->fields, cmd->nfields, ap);
  va_end(ap);

  ink_assert(msglen >= 0);

  req.ptr = static_cast<char *>(ats_malloc(msglen));
  req.len = msglen;

  // Marshall the message itself.
  va_start(ap, optype);
  if (mgmt_message_marshall_v(req.ptr, req.len, cmd->fields, cmd->nfields, ap) == -1) {
    ats_free(req.ptr);
    va_end(ap);
    return TS_ERR_PARAMS;
  }

  va_end(ap);

  MgmtMarshallInt op;
  MgmtMarshallString name;
  int down_time;
  static const MgmtMarshallType fieldso[] = {MGMT_MARSHALL_INT, MGMT_MARSHALL_STRING, MGMT_MARSHALL_INT};

  if (mgmt_message_parse(static_cast<void *>(req.ptr), msglen, fieldso, countof(fieldso), &op, &name, &down_time) == -1) {
    printf("Plugin message - RPC parsing error - message discarded.\n");
  }

  // Send the response as the payload of a data object.
  if (mgmt_message_write(fd, fields, countof(fields), &req) == -1) {
    ats_free(req.ptr);
    return TS_ERR_NET_WRITE;
  }

  ats_free(req.ptr);
  return TS_ERR_OKAY;
}

TSMgmtError
send_mgmt_error(int fd, OpType optype, TSMgmtError error)
{
  MgmtMarshallInt ecode     = error;
  MgmtMarshallInt intval    = 0;
  MgmtMarshallData dataval  = {nullptr, 0};
  MgmtMarshallString strval = nullptr;

  // Switch on operations, grouped by response format.
  switch (optype) {
  case OpType::BOUNCE:
  case OpType::STOP:
  case OpType::DRAIN:
  case OpType::EVENT_RESOLVE:
  case OpType::LIFECYCLE_MESSAGE:
  case OpType::PROXY_STATE_SET:
  case OpType::RECONFIGURE:
  case OpType::RESTART:
  case OpType::STATS_RESET_NODE:
  case OpType::HOST_STATUS_UP:
  case OpType::HOST_STATUS_DOWN:
  case OpType::STORAGE_DEVICE_CMD_OFFLINE:
    ink_release_assert(responses[static_cast<unsigned>(optype)].nfields == 1);
    return send_mgmt_response(fd, optype, &ecode);

  case OpType::RECORD_SET:
  case OpType::PROXY_STATE_GET:
  case OpType::EVENT_ACTIVE:
    ink_release_assert(responses[static_cast<unsigned>(optype)].nfields == 2);
    return send_mgmt_response(fd, optype, &ecode, &intval);

  case OpType::EVENT_GET_MLT:
  case OpType::SERVER_BACKTRACE:
    ink_release_assert(responses[static_cast<unsigned>(optype)].nfields == 2);
    return send_mgmt_response(fd, optype, &ecode, &strval);

  case OpType::RECORD_GET:
  case OpType::RECORD_MATCH_GET:
    ink_release_assert(responses[static_cast<unsigned>(optype)].nfields == 5);
    return send_mgmt_response(fd, optype, &ecode, &intval, &intval, &strval, &dataval);

  case OpType::RECORD_DESCRIBE_CONFIG:
    ink_release_assert(responses[static_cast<unsigned>(optype)].nfields == 15);
    return send_mgmt_response(fd, optype, &ecode, &strval /* name */, &dataval /* value */, &dataval /* default */,
                              &intval /* type */, &intval /* class */, &intval /* version */, &intval /* rsb */,
                              &intval /* order */, &intval /* access */, &intval /* update */, &intval /* updatetype */,
                              &intval /* checktype */, &intval /* source */, &strval /* checkexpr */);

  case OpType::EVENT_REG_CALLBACK:
  case OpType::EVENT_UNREG_CALLBACK:
  case OpType::EVENT_NOTIFY:
  case OpType::API_PING:
    /* no response for these */
    ink_release_assert(responses[static_cast<unsigned>(optype)].nfields == 0);
    return TS_ERR_OKAY;

  case OpType::UNDEFINED_OP:
    return TS_ERR_OKAY;
  }

  // We should never get here unless OpTypes are added without
  // updating the switch statement above. Don't do that; this
  // code must be able to handle every OpType.

  ink_fatal("missing generic error support for type %d management message", static_cast<int>(optype));
  return TS_ERR_FAIL;
}

// Send a management message response. We don't need to worry about retransmitting the message if we get
// disconnected, so this is much simpler. We can directly marshall the response as a data object.
TSMgmtError
send_mgmt_response(int fd, OpType optype, ...)
{
  va_list ap;
  MgmtMarshallInt msglen;
  MgmtMarshallData reply          = {nullptr, 0};
  const MgmtMarshallType fields[] = {MGMT_MARSHALL_DATA};
  const NetCmdOperation *cmd;

  GETCMD(responses, optype, cmd);

  va_start(ap, optype);
  msglen = mgmt_message_length_v(cmd->fields, cmd->nfields, ap);
  va_end(ap);

  ink_assert(msglen >= 0);

  reply.ptr = static_cast<char *>(ats_malloc(msglen));
  reply.len = msglen;

  // Marshall the message itself.
  va_start(ap, optype);
  if (mgmt_message_marshall_v(reply.ptr, reply.len, cmd->fields, cmd->nfields, ap) == -1) {
    ats_free(reply.ptr);
    va_end(ap);
    return TS_ERR_PARAMS;
  }

  va_end(ap);

  // Send the response as the payload of a data object.
  if (mgmt_message_write(fd, fields, countof(fields), &reply) == -1) {
    ats_free(reply.ptr);
    return TS_ERR_NET_WRITE;
  }

  ats_free(reply.ptr);
  return TS_ERR_OKAY;
}

template <unsigned N>
static TSMgmtError
recv_x(const struct NetCmdOperation (&ops)[N], void *buf, size_t buflen, OpType optype, va_list ap)
{
  ssize_t msglen;
  const NetCmdOperation *cmd;

  GETCMD(ops, optype, cmd);

  msglen = mgmt_message_parse_v(buf, buflen, cmd->fields, cmd->nfields, ap);
  return (msglen == -1) ? TS_ERR_PARAMS : TS_ERR_OKAY;
}

TSMgmtError
recv_mgmt_request(void *buf, size_t buflen, OpType optype, ...)
{
  TSMgmtError err;
  va_list ap;

  va_start(ap, optype);
  err = recv_x(requests, buf, buflen, optype, ap);
  va_end(ap);

  return err;
}

TSMgmtError
recv_mgmt_response(void *buf, size_t buflen, OpType optype, ...)
{
  TSMgmtError err;
  va_list ap;

  va_start(ap, optype);
  err = recv_x(responses, buf, buflen, optype, ap);
  va_end(ap);

  return err;
}

TSMgmtError
recv_mgmt_message(int fd, MgmtMarshallData &msg)
{
  const MgmtMarshallType fields[] = {MGMT_MARSHALL_DATA};

  if (mgmt_message_read(fd, fields, countof(fields), &msg) == -1) {
    return TS_ERR_NET_READ;
  }

  return TS_ERR_OKAY;
}

OpType
extract_mgmt_request_optype(void *msg, size_t msglen)
{
  const MgmtMarshallType fields[] = {MGMT_MARSHALL_INT};
  MgmtMarshallInt optype;

  if (mgmt_message_parse(msg, msglen, fields, countof(fields), &optype) == -1) {
    return OpType::UNDEFINED_OP;
  }

  return static_cast<OpType>(optype);
}
