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

#define _POSIX_C_SOURCE 200809L  // for strnlen
#include <arpa/inet.h>
#include <ctype.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>

#include "internal.h"

// TODO: update this
// RRQ    ->
//        <- DATA or OACK or ERROR
// ACK(0) -> (to confirm reception of OACK)
// ERROR  -> (on OACK with non requested options)
//        <- DATA(1)
// ACK(1) ->

// WRQ     ->
//         <- ACK or OACK or ERROR
// DATA(1) ->
// ERROR   -> (on OACK with non requested options)
//        <- DATA(2)
// ACK(2) ->

// MODE
static const char* kNetascii = "NETASCII";
static const char* kOctet = "OCTET";
static const char* kMail = "MAIL";
static const size_t kMaxMode = 9;  // strlen(NETASCII) + 1

// TSIZE
// Limit transfer to less than 10GB
static const char* kTsize = "TSIZE";
static const size_t kTsizeLen = 5;      // strlen(kTsize)
static const size_t kMaxTsizeOpt = 17;  // strlen(TSIZE) + 1 + strlen(1000000000) + 1

// BLKSIZE
// Max size is 65535 (max IP datagram)
static const char* kBlkSize = "BLKSIZE";
static const size_t kBlkSizeLen = 7;      // strlen(kBlkSize)
static const size_t kMaxBlkSizeOpt = 15;  // kBlkSizeLen + strlen("!") + 1 + strlen(65535) + 1

// TIMEOUT
// Max is 255 (RFC 2349)
static const char* kTimeout = "TIMEOUT";
static const size_t kTimeoutLen = 7;      // strlen(kTimeout)
static const size_t kMaxTimeoutOpt = 13;  // kTimeoutLen + strlen("!") + 1 + strlen(255) + 1;

// WINDOWSIZE
// Max is 65535 (RFC 7440)
static const char* kWindowSize = "WINDOWSIZE";
static const size_t kWindowSizeLen = 10;  // strlen(kWindowSize);
static const size_t kMaxWindowSizeOpt =
    18;  // kWindowSizeLen + strlen("!") + 1 + strlen(65535) + 1;

// Since RRQ and WRQ come before option negotation, they are limited to max TFTP
// blocksize of 512 (RFC 1350 and 2347).
static const size_t kMaxRequestSize = 512;

#if defined(TFTP_HOSTLIB)
// Host (e.g., netcp, bootserver)
#include <time.h>
#define DEBUG 0
#elif defined(TFTP_USERLIB)
// Fuchsia (e.g., netsvc)
#define DEBUG 0
#elif defined(TFTP_EFILIB)
// Bootloader: use judiciously, since the console can easily become overwhelmed and hang
#define DEBUG 0
#else
#error unable to identify target environment
#endif

#if DEBUG
#define xprintf(args...) fprintf(stderr, args)
#else
#define xprintf(args...)
#endif

#define __ATTR_PRINTF(__fmt, __varargs) __attribute__((__format__(__printf__, __fmt, __varargs)))
#define MIN(x, y) ((x) < (y) ? (x) : (y))

static void append_option_name(char** body, size_t* left, const char* name) {
  size_t offset = strlen(name);
  memcpy(*body, name, offset);
  offset++;
  *body += offset;
  *left -= offset;
}

static void __ATTR_PRINTF(5, 6)
    append_option(char** body, size_t* left, const char* name, bool force, const char* fmt, ...) {
  char* bodyp = *body;
  size_t leftp = *left;

  size_t offset = strlen(name);
  memcpy(bodyp, name, offset);
  if (force) {
    bodyp[offset] = '!';
    offset++;
  }
  offset++;
  bodyp += offset;
  leftp -= offset;
  va_list args;
  va_start(args, fmt);
  offset = vsnprintf(bodyp, leftp - 1, fmt, args);
  va_end(args);
  offset++;
  bodyp += offset;
  leftp -= offset;

  *body = bodyp;
  *left = leftp;
}

#define OPCODE(session, msg, value)                                                    \
  do {                                                                                 \
    if (session->use_opcode_prefix) {                                                  \
      (msg)->opcode = htons((value & 0xff) | ((uint16_t)session->opcode_prefix << 8)); \
    } else {                                                                           \
      (msg)->opcode = htons(value);                                                    \
    }                                                                                  \
  } while (0)

#define TRANSMIT_MORE 1
#define TRANSMIT_WAIT_ON_ACK 2

static size_t next_option(char* buffer, size_t len, char** option, char** value) {
  size_t left = len;
  size_t option_len = strnlen(buffer, left);
  if (option_len == len) {
    return 0;
  }

  *option = buffer;
  xprintf("'%s' %ld\n", *option, option_len);
  buffer += option_len + 1;
  left -= option_len + 1;
  size_t value_len = strnlen(buffer, left);
  if (value_len == left) {
    return 0;
  }
  *value = buffer;
  xprintf("'%s' %ld\n", *value, value_len);
  left -= value_len + 1;
  return len - left;
}

/* Build an err packet in resp_buf and set session state to ERROR

     2 bytes        2 bytes    string   1 byte
   +--------------+----------+---------+------+
   | OPCODE_ERROR | ERR_CODE | ERR_MSG |   0  |
   +--------------+----------+---------+------+
*/
static void set_error(tftp_session* session, uint16_t err_code, void* resp_buf, size_t* resp_len,
                      const char* err_msg) {
  tftp_err_msg* resp = resp_buf;
  OPCODE(session, resp, OPCODE_ERROR);
  resp->err_code = htons(err_code);
  size_t err_msg_len = strlen(err_msg);
  size_t max_msg_sz = *resp_len - (sizeof(tftp_err_msg) + 1);
  if (err_msg_len >= max_msg_sz) {
    memcpy(resp->msg, err_msg, max_msg_sz);
    resp->msg[max_msg_sz] = '\0';
    // *resp_len is unchanged - the whole buffer was used
  } else {
    strcpy(resp->msg, err_msg);
    *resp_len = sizeof(tftp_err_msg) + err_msg_len + 1;
  }
  session->state = ERROR;
}

tftp_status tx_data(tftp_session* session, tftp_data_msg* resp, size_t* outlen, void* cookie) {
  session->offset = (session->block_number + session->window_index) * session->block_size;
  *outlen = 0;
  if (session->offset <= session->file_size) {
    session->window_index++;
    OPCODE(session, resp, OPCODE_DATA);
    resp->block = htons(session->block_number + session->window_index);
    size_t len = MIN(session->file_size - session->offset, session->block_size);
    xprintf(" -> Copying block #%" PRIu64 " (size:%zu/%d) from %zu/%zu [%d/%d]\n",
            session->block_number + session->window_index, len, session->block_size,
            session->offset, session->file_size, session->window_index, session->window_size);
    void* buf = resp->data;
    size_t len_remaining = len;
    size_t off = session->offset;
    while (len_remaining > 0) {
      // TODO(tkilbourn): assert that these function pointers are set
      size_t rr = len_remaining;
      tftp_status s = session->file_interface.read(buf, &rr, off, cookie);
      if (s < 0) {
        xprintf("Err reading: %d\n", s);
        return s;
      }
      buf += rr;
      off += rr;
      len_remaining -= rr;
    }
    *outlen = sizeof(*resp) + len;

    if (session->window_index < session->window_size) {
      xprintf(" -> TRANSMIT_MORE(%d < %d)\n", session->window_index, session->window_size);
    } else {
      xprintf(" -> TRANSMIT_WAIT_ON_ACK(%d >= %d)\n", session->window_index, session->window_size);
    }
  } else {
    xprintf(" -> TRANSMIT_WAIT_ON_ACK(completed)\n");
  }
  return TFTP_NO_ERROR;
}

size_t tftp_sizeof_session(void) { return sizeof(tftp_session); }

tftp_status tftp_init(tftp_session** session, void* buffer, size_t size) {
  if (buffer == NULL) {
    return TFTP_ERR_INVALID_ARGS;
  }
  if (size < sizeof(tftp_session)) {
    return TFTP_ERR_BUFFER_TOO_SMALL;
  }
  *session = buffer;
  tftp_session* s = *session;
  memset(s, 0, sizeof(tftp_session));

  // Sensible defaults for non-negotiated values
  s->file_size = DEFAULT_FILESIZE;
  s->mode = DEFAULT_MODE;
  s->max_timeouts = DEFAULT_MAX_TIMEOUTS;
  s->use_opcode_prefix = DEFAULT_USE_OPCODE_PREFIX;

  return TFTP_NO_ERROR;
}

tftp_status tftp_session_set_file_interface(tftp_session* session, tftp_file_interface* callbacks) {
  if (session == NULL) {
    return TFTP_ERR_INVALID_ARGS;
  }

  session->file_interface = *callbacks;
  return TFTP_NO_ERROR;
}

tftp_status tftp_session_set_transport_interface(tftp_session* session,
                                                 tftp_transport_interface* callbacks) {
  if (session == NULL) {
    return TFTP_ERR_INVALID_ARGS;
  }
  session->transport_interface = *callbacks;
  return TFTP_NO_ERROR;
}

bool tftp_session_has_pending(tftp_session* session) {
  return session->direction == SEND_FILE && session->window_index > 0 &&
         session->window_index < session->window_size &&
         ((session->block_number + session->window_index) * session->block_size) <=
             session->file_size;
}

tftp_status tftp_set_options(tftp_session* session, const uint16_t* block_size,
                             const uint8_t* timeout, const uint16_t* window_size) {
  session->options.mask = 0;
  if (block_size) {
    session->options.block_size = *block_size;
    session->options.mask |= BLOCKSIZE_OPTION;
  }
  if (timeout) {
    session->options.timeout = *timeout;
    session->options.mask |= TIMEOUT_OPTION;
  }
  if (window_size) {
    session->options.window_size = *window_size;
    session->options.mask |= WINDOWSIZE_OPTION;
  }
  return TFTP_NO_ERROR;
}

tftp_status tftp_generate_request(tftp_session* session, tftp_file_direction direction,
                                  const char* local_filename, const char* remote_filename,
                                  tftp_mode mode, size_t datalen, const uint16_t* block_size,
                                  const uint8_t* timeout, const uint16_t* window_size,
                                  void* outgoing, size_t* outlen, uint32_t* timeout_ms) {
  if (*outlen < 2) {
    xprintf("outlen too short: %zd\n", *outlen);
    return TFTP_ERR_BUFFER_TOO_SMALL;
  }

  // The actual options are not set until we get a confirmation OACK message. Until then,
  // we have to assume the TFTP defaults.
  session->block_size = DEFAULT_BLOCKSIZE;
  session->timeout = DEFAULT_TIMEOUT;
  session->window_size = DEFAULT_WINDOWSIZE;

  tftp_msg* ack = outgoing;
  OPCODE(session, ack, (direction == SEND_FILE) ? OPCODE_WRQ : OPCODE_RRQ);
  char* body = ack->data;
  memset(body, 0, *outlen - sizeof(*ack));
  size_t left = *outlen - sizeof(*ack);
  size_t remote_filename_len = strlen(remote_filename);
  if (remote_filename_len + 1 > left - kMaxMode) {
    xprintf("filename too long %zd > %zd\n", remote_filename_len, left - kMaxMode);
    return TFTP_ERR_INVALID_ARGS;
  }
  memcpy(body, remote_filename, remote_filename_len);
  body += remote_filename_len + 1;
  left -= remote_filename_len + 1;
  strncpy(session->filename, local_filename, sizeof(session->filename) - 1);
  session->filename[sizeof(session->filename) - 1] = '\0';
  switch (mode) {
    case MODE_NETASCII:
      append_option_name(&body, &left, kNetascii);
      break;
    case MODE_OCTET:
      append_option_name(&body, &left, kOctet);
      break;
    case MODE_MAIL:
      append_option_name(&body, &left, kMail);
      break;
    default:
      return TFTP_ERR_INVALID_ARGS;
  }
  session->mode = mode;

  if (left < kMaxTsizeOpt) {
    return TFTP_ERR_BUFFER_TOO_SMALL;
  }
  append_option(&body, &left, kTsize, false, "%zu", datalen);
  session->file_size = datalen;
  tftp_options* sent_opts = &session->client_sent_opts;
  sent_opts->mask = 0;

  if (block_size || session->options.mask & BLOCKSIZE_OPTION) {
    if (left < kMaxBlkSizeOpt) {
      return TFTP_ERR_BUFFER_TOO_SMALL;
    }
    bool force_value;
    if (block_size) {
      force_value = true;
      sent_opts->block_size = *block_size;
    } else {
      force_value = false;
      sent_opts->block_size = session->options.block_size;
    }
    append_option(&body, &left, kBlkSize, force_value, "%" PRIu16, sent_opts->block_size);
    sent_opts->mask |= BLOCKSIZE_OPTION;
  }

  if (timeout || session->options.mask & TIMEOUT_OPTION) {
    if (left < kMaxTimeoutOpt) {
      return TFTP_ERR_BUFFER_TOO_SMALL;
    }
    bool force_value;
    if (timeout) {
      force_value = true;
      sent_opts->timeout = *timeout;
    } else {
      force_value = false;
      sent_opts->timeout = session->options.timeout;
    }
    append_option(&body, &left, kTimeout, force_value, "%" PRIu8, sent_opts->timeout);
    sent_opts->mask |= TIMEOUT_OPTION;
  }

  if (window_size || session->options.mask & WINDOWSIZE_OPTION) {
    if (left < kMaxWindowSizeOpt) {
      return TFTP_ERR_BUFFER_TOO_SMALL;
    }
    bool force_value;
    if (window_size) {
      force_value = true;
      sent_opts->window_size = *window_size;
    } else {
      force_value = false;
      sent_opts->window_size = session->options.window_size;
    }
    append_option(&body, &left, kWindowSize, force_value, "%" PRIu16, sent_opts->window_size);
    sent_opts->mask |= WINDOWSIZE_OPTION;
  }

  *outlen = *outlen - left;
  // Nothing has been negotiated yet so use default
  *timeout_ms = 1000 * session->timeout;

  session->direction = direction;
  session->state = REQ_SENT;
  xprintf("Generated %s request, len=%zu\n", (direction == SEND_FILE) ? "write" : "read", *outlen);
  return TFTP_NO_ERROR;
}

tftp_status tftp_handle_request(tftp_session* session, tftp_file_direction direction, tftp_msg* req,
                                size_t req_len, tftp_msg* resp, size_t* resp_len,
                                uint32_t* timeout_ms, void* cookie) {
  // We could be in REQ_RECEIVED if our OACK was dropped.
  if (session->state != NONE && session->state != REQ_RECEIVED) {
    xprintf("Invalid state transition %d -> %d\n", session->state, REQ_RECEIVED);
    set_error(session, TFTP_ERR_CODE_UNDEF, resp, resp_len, "invalid state transition");
    return TFTP_ERR_BAD_STATE;
  }
  // opcode, filename, 0, mode, 0, opt1, 0, value1 ... optN, 0, valueN, 0
  // Max length is 512 no matter
  if (req_len > kMaxRequestSize) {
    xprintf("Write request is too large\n");
    set_error(session, TFTP_ERR_CODE_UNDEF, resp, resp_len, "write request is too large");
    return TFTP_ERR_INTERNAL;
  }
  // Skip opcode
  size_t left = req_len - sizeof(*resp);
  char* cur = req->data;
  char *option, *value;
  // filename, 0, mode, 0 can be interpreted like option, 0, value, 0
  size_t offset = next_option(cur, left, &option, &value);
  if (!offset) {
    xprintf("No options\n");
    set_error(session, TFTP_ERR_CODE_BAD_OPTIONS, resp, resp_len, "no options");
    return TFTP_ERR_INTERNAL;
  }
  left -= offset;

  xprintf("filename = '%s', mode = '%s'\n", option, value);

  strncpy(session->filename, option, sizeof(session->filename) - 1);
  session->filename[sizeof(session->filename) - 1] = '\0';
  char* mode = value;
  if (!strncasecmp(mode, kNetascii, strlen(kNetascii))) {
    session->mode = MODE_NETASCII;
  } else if (!strncasecmp(mode, kOctet, strlen(kOctet))) {
    session->mode = MODE_OCTET;
  } else if (!strncasecmp(mode, kMail, strlen(kMail))) {
    session->mode = MODE_MAIL;
  } else {
    xprintf("Unknown write request mode\n");
    set_error(session, TFTP_ERR_CODE_BAD_OPTIONS, resp, resp_len, "unknown write request mode");
    return TFTP_ERR_INTERNAL;
  }

  // Initialize the values to TFTP defaults
  session->block_size = DEFAULT_BLOCKSIZE;
  session->timeout = DEFAULT_TIMEOUT;
  session->window_size = DEFAULT_WINDOWSIZE;

  // TODO(tkilbourn): refactor option handling code to share with
  // tftp_handle_oack
  cur += offset;
  bool file_size_seen = false;
  tftp_options requested_options = {.mask = 0};
  tftp_options* override_opts = &session->options;
  while (offset > 0 && left > 0) {
    offset = next_option(cur, left, &option, &value);
    if (!offset) {
      xprintf("No more options\n");
      set_error(session, TFTP_ERR_CODE_BAD_OPTIONS, resp, resp_len, "no more options");
      return TFTP_ERR_INTERNAL;
    }

    if (!strncasecmp(option, kTsize, kTsizeLen)) {  // RFC 2349
      if (direction == RECV_FILE) {
        long val = atol(value);
        if (val < 0) {
          xprintf("invalid file size\n");
          set_error(session, TFTP_ERR_CODE_BAD_OPTIONS, resp, resp_len, "invalid file size");
          return TFTP_ERR_INTERNAL;
        }
        session->file_size = val;
      }
      file_size_seen = true;
    } else if (!strncasecmp(option, kBlkSize, kBlkSizeLen)) {  // RFC 2348
      bool force_block_size = (option[kBlkSizeLen] == '!');
      // Valid values range between "8" and "65464" octets, inclusive
      long val = atol(value);
      // TODO(tkilbourn): with an MTU of 1500, shouldn't be more than 1428
      if (val < 8 || val > 65464) {
        xprintf("invalid block size\n");
        set_error(session, TFTP_ERR_CODE_BAD_OPTIONS, resp, resp_len, "invalid block size");
        return TFTP_ERR_INTERNAL;
      }
      requested_options.block_size = val;
      requested_options.mask |= BLOCKSIZE_OPTION;
      if (force_block_size || !(override_opts->mask & BLOCKSIZE_OPTION)) {
        session->block_size = val;
      } else {
        session->block_size = override_opts->block_size;
      }
    } else if (!strncasecmp(option, kTimeout, kTimeoutLen)) {  // RFC 2349
      bool force_timeout_val = (option[kTimeoutLen] == '!');
      // Valid values range between "1" and "255" seconds inclusive.
      long val = atol(value);
      if (val < 1 || val > 255) {
        xprintf("invalid timeout\n");
        set_error(session, TFTP_ERR_CODE_BAD_OPTIONS, resp, resp_len, "invalid timeout");
        return TFTP_ERR_INTERNAL;
      }
      requested_options.timeout = val;
      requested_options.mask |= TIMEOUT_OPTION;
      if (force_timeout_val || !(override_opts->mask & TIMEOUT_OPTION)) {
        session->timeout = val;
      } else {
        session->timeout = override_opts->timeout;
      }
    } else if (!strncasecmp(option, kWindowSize, kWindowSizeLen)) {  // RFC 7440
      bool force_window_size = (option[kWindowSizeLen] == '!');
      // The valid values range MUST be between 1 and 65535 blocks, inclusive.
      long val = atol(value);
      if (val < 1 || val > 65535) {
        xprintf("invalid window size\n");
        set_error(session, TFTP_ERR_CODE_BAD_OPTIONS, resp, resp_len, "invalid window size");
        return TFTP_ERR_INTERNAL;
      }
      requested_options.window_size = val;
      requested_options.mask |= WINDOWSIZE_OPTION;
      if (force_window_size || !(override_opts->mask & WINDOWSIZE_OPTION)) {
        session->window_size = val;
      } else {
        session->window_size = override_opts->window_size;
      }
    } else {
      // Options which the server does not support should be omitted from the
      // OACK; they should not cause an ERROR packet to be generated.
    }

    cur += offset;
    left -= offset;
  }

  char* body = resp->data;
  memset(body, 0, *resp_len - sizeof(*resp));
  left = *resp_len - sizeof(*resp);

  OPCODE(session, resp, OPCODE_OACK);

  // Open file, if we haven't already
  if (session->state == NONE) {
    if (direction == RECV_FILE) {
      if (!session->file_interface.open_write) {
        xprintf("Unable to service write request: no open_write implementation\n");
        set_error(session, TFTP_ERR_CODE_UNDEF, resp, resp_len, "internal error");
        return TFTP_ERR_BAD_STATE;
      }
      switch (session->file_interface.open_write(session->filename, session->file_size,
                                                 session->timeout, cookie)) {
        case TFTP_ERR_SHOULD_WAIT:
          // The open_write() callback can return an ERR_SHOULD_WAIT response if it isn't
          // prepared to service another request at the moment and the client should retry
          // later.
          xprintf("Denying write request received when not ready\n");
          set_error(session, TFTP_ERR_CODE_BUSY, resp, resp_len, "not ready to receive");
          session->state = NONE;
          return TFTP_ERR_SHOULD_WAIT;
        case TFTP_NO_ERROR:
          break;
        default:
          xprintf("Could not open file on write request\n");
          set_error(session, TFTP_ERR_CODE_ACCESS_VIOLATION, resp, resp_len,
                    "could not open file for writing");
          return TFTP_ERR_BAD_STATE;
      }
    } else {
      ssize_t file_size;
      if (!session->file_interface.open_read) {
        xprintf("Unable to service read request: no open_read implementation\n");
        set_error(session, TFTP_ERR_CODE_UNDEF, resp, resp_len, "internal error");
        return TFTP_ERR_BAD_STATE;
      }

      file_size = session->file_interface.open_read(session->filename, session->timeout, cookie);
      if (file_size == TFTP_ERR_SHOULD_WAIT) {
        // The open_read() callback can return an ERR_SHOULD_WAIT response if it isn't
        // prepared to service another request at the moment and the client should retry
        // later.
        xprintf("Denying read request received when not ready\n");
        set_error(session, TFTP_ERR_CODE_BUSY, resp, resp_len, "not ready to send");
        session->state = NONE;
        return TFTP_ERR_SHOULD_WAIT;
      }
      if (file_size < 0) {
        xprintf("Unable to open file %s for reading\n", session->filename);
        set_error(session, TFTP_ERR_CODE_FILE_NOT_FOUND, resp, resp_len,
                  "could not open file for reading");
        return TFTP_ERR_BAD_STATE;
      }
      session->file_size = file_size;
    }
  }

  if (file_size_seen) {
    append_option(&body, &left, kTsize, false, "%zu", session->file_size);
  } else {
    xprintf("No TSIZE option specified\n");
    set_error(session, TFTP_ERR_CODE_BAD_OPTIONS, resp, resp_len, "no TSIZE option");
    if (session->file_interface.close) {
      session->file_interface.close(cookie);
    }
    return TFTP_ERR_BAD_STATE;
  }
  if (requested_options.mask & BLOCKSIZE_OPTION) {
    // TODO(jpoichet) Make sure this block size is possible. Need API upwards to
    // request allocation of block size * window size memory
    append_option(&body, &left, kBlkSize, false, "%d", session->block_size);
  }
  if (requested_options.mask & TIMEOUT_OPTION) {
    // TODO(jpoichet) Make sure this timeout is possible. Need API upwards to
    // request allocation of block size * window size memory
    append_option(&body, &left, kTimeout, false, "%d", session->timeout);
    *timeout_ms = 1000 * session->timeout;
  }
  if (requested_options.mask & WINDOWSIZE_OPTION) {
    append_option(&body, &left, kWindowSize, false, "%d", session->window_size);
  }
  *resp_len = *resp_len - left;
  session->state = REQ_RECEIVED;
  session->direction = direction;

  xprintf("%s Request Parsed\n", (direction == SEND_FILE) ? "Read" : "Write");
  xprintf("    Mode       : %s\n",
          session->mode == MODE_NETASCII
              ? "netascii"
              : session->mode == MODE_OCTET ? "octet"
                                            : session->mode == MODE_MAIL ? "mail" : "unrecognized");
  xprintf("    File Size  : %zu\n", session->file_size);
  xprintf("Options requested: %08x\n", requested_options.mask);
  xprintf("    Block Size : %d\n", requested_options.block_size);
  xprintf("    Timeout    : %d\n", requested_options.timeout);
  xprintf("    Window Size: %d\n", requested_options.window_size);
  xprintf("Using options\n");
  xprintf("    Block Size : %d\n", session->block_size);
  xprintf("    Timeout    : %d\n", session->timeout);
  xprintf("    Window Size: %d\n", session->window_size);

  return TFTP_NO_ERROR;
}

tftp_status tftp_handle_wrq(tftp_session* session, tftp_msg* wrq, size_t wrq_len, tftp_msg* resp,
                            size_t* resp_len, uint32_t* timeout_ms, void* cookie) {
  return tftp_handle_request(session, RECV_FILE, wrq, wrq_len, resp, resp_len, timeout_ms, cookie);
}

tftp_status tftp_handle_rrq(tftp_session* session, tftp_msg* rrq, size_t rrq_len, tftp_msg* resp,
                            size_t* resp_len, uint32_t* timeout_ms, void* cookie) {
  return tftp_handle_request(session, SEND_FILE, rrq, rrq_len, resp, resp_len, timeout_ms, cookie);
}

static void tftp_prepare_ack(tftp_session* session, tftp_msg* msg, size_t* msg_len) {
  tftp_data_msg* ack_data = (tftp_data_msg*)msg;
  xprintf(" -> Ack %" PRIu64 "\n", session->block_number);
  session->window_index = 0;
  OPCODE(session, ack_data, OPCODE_ACK);
  ack_data->block = htons(session->block_number & 0xffff);
  *msg_len = sizeof(*ack_data);
}

tftp_status tftp_handle_data(tftp_session* session, tftp_msg* msg, size_t msg_len, tftp_msg* resp,
                             size_t* resp_len, uint32_t* timeout_ms, void* cookie) {
  if ((session->direction == RECV_FILE) &&
      ((session->state == REQ_RECEIVED) || (session->state == FIRST_DATA) ||
       (session->state == RECEIVING_DATA))) {
    session->state = RECEIVING_DATA;
  } else {
    set_error(session, TFTP_ERR_CODE_UNDEF, resp, resp_len, "internal error: bad state");
    return TFTP_ERR_INTERNAL;
  }

  tftp_data_msg* data = (tftp_data_msg*)msg;

  uint16_t block_num = ntohs(data->block);

  // The block field of the message is only 16 bits wide. To support large files
  // (> 65535 * blocksize bytes), we allow the block number to wrap. We use signed modulo
  // math to determine the relative location of the block to our current position.
  int16_t block_delta = block_num - (uint16_t)session->block_number;
  xprintf(" <- Block %" PRIu64 " (Last = %" PRIu64 ", Offset = %" PRIu64
          ", Size = %zd, Left = %" PRIu64 ")\n",
          session->block_number + block_delta, session->block_number,
          session->block_number * session->block_size, session->file_size,
          session->file_size - session->block_number * session->block_size);
  if (block_delta == 1) {
    xprintf("Advancing normally + 1\n");
    session->metrics.inorder_blocks++;
    void* buf = data->data;
    size_t len = msg_len - sizeof(tftp_data_msg);
    size_t off = session->block_number * session->block_size;
    while (len > 0) {
      tftp_status ret;
      // TODO(tkilbourn): assert that these function pointers are set
      size_t wr = len;
      ret = session->file_interface.write(buf, &wr, off, cookie);
      if (ret < 0) {
        xprintf("Error writing: %d\n", ret);
        return ret;
      }
      session->metrics.inorder_bytes += wr;
      buf += wr;
      off += wr;
      len -= wr;
    }
    session->block_number++;
    session->window_index++;
  } else if (block_delta > 1) {
    session->metrics.outoforder_blocks++;
    // Force sending a ACK with the last block_number we received
    xprintf("Skipped: got %" PRIu64 ", expected %" PRIu64 "\n", session->block_number + block_delta,
            session->block_number + 1);
    session->window_index = session->window_size;
    // It's possible that a previous ACK wasn't received, increment the prefix
    if (session->use_opcode_prefix) {
      session->opcode_prefix++;
    }
  }

  if (session->window_index == session->window_size ||
      session->block_number * session->block_size > session->file_size) {
    tftp_prepare_ack(session, resp, resp_len);
    if (block_delta > 1) {
      session->metrics.nacks_sent++;
    } else {
      session->metrics.acks_sent++;
    }
    if (session->block_number * session->block_size > session->file_size) {
      return TFTP_TRANSFER_COMPLETED;
    }
  } else {
    // Nothing to send
    *resp_len = 0;
  }
  return TFTP_NO_ERROR;
}

tftp_status tftp_handle_ack(tftp_session* session, tftp_msg* ack, size_t ack_len, tftp_msg* resp,
                            size_t* resp_len, uint32_t* timeout_ms, void* cookie) {
  if ((session->direction != SEND_FILE) ||
      ((session->state != FIRST_DATA) && (session->state != REQ_RECEIVED) &&
       (session->state != SENDING_DATA))) {
    set_error(session, TFTP_ERR_CODE_UNDEF, resp, resp_len, "internal error: bad state");
    return TFTP_ERR_INTERNAL;
  }
  // Need to move forward in data and send it
  tftp_data_msg* ack_data = (void*)ack;
  tftp_data_msg* resp_data = (void*)resp;

  uint16_t ack_block = ntohs(ack_data->block);
  xprintf(" <- Ack %d\n", ack_block);

  // Since we track blocks in 32 bits, but the packets only support 16 bits, calculate the
  // signed 16 bit offset to determine the adjustment to the current position.
  int16_t block_offset = ack_block - (uint16_t)session->block_number;

  if (session->state != FIRST_DATA && session->state != REQ_RECEIVED && block_offset == 0) {
    session->metrics.sas_events++;
    // Don't acknowledge duplicate ACKs, avoiding the "Sorcerer's Apprentice Syndrome"
    *resp_len = 0;
    return TFTP_NO_ERROR;
  }

  if (block_offset < session->window_size) {
    // If it looks like some of our data might have been dropped, modify the prefix
    // before resending.
    if (session->use_opcode_prefix) {
      session->opcode_prefix++;
    }
  }
  session->state = SENDING_DATA;
  session->block_number += block_offset;
  session->window_index = 0;

  if (session->block_number * session->block_size > session->file_size) {
    *resp_len = 0;
    return TFTP_TRANSFER_COMPLETED;
  }

  tftp_status ret = tx_data(session, resp_data, resp_len, cookie);
  if (ret < 0) {
    set_error(session, TFTP_ERR_CODE_UNDEF, resp, resp_len, "could not transmit data");
  }
  return ret;
}

tftp_status tftp_handle_error(tftp_session* session, tftp_err_msg* err, size_t err_len,
                              tftp_msg* resp, size_t* resp_len, uint32_t* timeout_ms,
                              void* cookie) {
  if (err_len < sizeof(tftp_err_msg)) {
    return TFTP_ERR_BUFFER_TOO_SMALL;
  }
  uint16_t err_code = ntohs(err->err_code);

  // There's no need to respond to an error
  *resp_len = 0;

  if (err_code == TFTP_ERR_CODE_BUSY) {
    xprintf("Target busy\n");
    session->state = NONE;
    return TFTP_ERR_SHOULD_WAIT;
  }
  xprintf("Target sent error %d\n", err_code);
  session->state = ERROR;
  return TFTP_ERR_INTERNAL;
}

tftp_status tftp_handle_oack(tftp_session* session, tftp_msg* oack, size_t oack_len, tftp_msg* resp,
                             size_t* resp_len, uint32_t* timeout_ms, void* cookie) {
  xprintf("Option Ack\n");
  if (session->state == REQ_SENT || session->state == FIRST_DATA) {
    session->state = FIRST_DATA;
  }

  size_t left = oack_len - sizeof(*oack);
  char* cur = oack->data;
  size_t offset;
  char *option, *value;

  while (left > 0) {
    offset = next_option(cur, left, &option, &value);
    if (!offset) {
      set_error(session, TFTP_ERR_CODE_BAD_OPTIONS, resp, resp_len, "invalid option format");
      return TFTP_ERR_INTERNAL;
    }

    if (!strncasecmp(option, kTsize, kTsizeLen)) {  // RFC 2349
      if (session->direction == RECV_FILE) {
        session->file_size = atol(value);
      }
      // If we are sending the file, we don't care what value the server wrote in here
    } else if (!strncasecmp(option, kBlkSize, kBlkSizeLen)) {  // RFC 2348
      if (!(session->client_sent_opts.mask & BLOCKSIZE_OPTION)) {
        xprintf("block size not requested\n");
        set_error(session, TFTP_ERR_CODE_BAD_OPTIONS, resp, resp_len, "no block size");
        return TFTP_ERR_INTERNAL;
      }
      // Valid values range between "8" and "65464" octets, inclusive
      long val = atol(value);
      if (val < 8 || val > 65464) {
        xprintf("invalid block size\n");
        set_error(session, TFTP_ERR_CODE_BAD_OPTIONS, resp, resp_len, "invalid block size");
        return TFTP_ERR_INTERNAL;
      }
      // TODO(tkilbourn): with an MTU of 1500, shouldn't be more than 1428
      session->block_size = val;
    } else if (!strncasecmp(option, kTimeout, kTimeoutLen)) {  // RFC 2349
      if (!(session->client_sent_opts.mask & TIMEOUT_OPTION)) {
        xprintf("timeout not requested\n");
        set_error(session, TFTP_ERR_CODE_BAD_OPTIONS, resp, resp_len, "no timeout");
        return TFTP_ERR_INTERNAL;
      }
      // Valid values range between "1" and "255" seconds inclusive.
      long val = atol(value);
      if (val < 1 || val > 255) {
        xprintf("invalid timeout\n");
        set_error(session, TFTP_ERR_CODE_BAD_OPTIONS, resp, resp_len, "invalid timeout");
        return TFTP_ERR_INTERNAL;
      }
      session->timeout = val;
    } else if (!strncasecmp(option, kWindowSize, kWindowSizeLen)) {  // RFC 7440
      if (!(session->client_sent_opts.mask & WINDOWSIZE_OPTION)) {
        xprintf("window size not requested\n");
        set_error(session, TFTP_ERR_CODE_BAD_OPTIONS, resp, resp_len, "no window size");
        return TFTP_ERR_INTERNAL;
      }
      // The valid values range MUST be between 1 and 65535 blocks, inclusive.
      long val = atol(value);
      if (val < 1 || val > 65535) {
        xprintf("invalid window size\n");
        set_error(session, TFTP_ERR_CODE_BAD_OPTIONS, resp, resp_len, "invalid window size");
        return TFTP_ERR_INTERNAL;
      }
      session->window_size = val;
    } else {
      // Options which the server does not support should be omitted from the
      // OACK; they should not cause an ERROR packet to be generated.
    }

    cur += offset;
    left -= offset;
  }
  *timeout_ms = 1000 * session->timeout;

  xprintf("Options negotiated\n");
  xprintf("    File Size  : %zu\n", session->file_size);
  xprintf("    Block Size : %d\n", session->block_size);
  xprintf("    Timeout    : %d\n", session->timeout);
  xprintf("    Window Size: %d\n", session->window_size);

  session->offset = 0;
  session->block_number = 0;
  session->window_index = 0;

  if (session->direction == SEND_FILE) {
    tftp_data_msg* resp_data = (void*)resp;
    tftp_status ret = tx_data(session, resp_data, resp_len, cookie);
    if (ret < 0) {
      set_error(session, TFTP_ERR_CODE_UNDEF, resp, resp_len, "failure to transmit data");
    }
    return ret;
  } else {
    if (!session->file_interface.open_write ||
        session->file_interface.open_write(session->filename, session->file_size, session->timeout,
                                           cookie)) {
      xprintf("Could not open file on write request\n");
      set_error(session, TFTP_ERR_CODE_UNDEF, resp, resp_len, "could not open file for writing");
      return TFTP_ERR_BAD_STATE;
    }
    tftp_prepare_ack(session, resp, resp_len);
    session->metrics.acks_sent++;
    return TFTP_NO_ERROR;
  }
}

tftp_status tftp_process_msg(tftp_session* session, void* incoming, size_t inlen, void* outgoing,
                             size_t* outlen, uint32_t* timeout_ms, void* cookie) {
  if (inlen < sizeof(tftp_msg)) {
    return TFTP_ERR_BUFFER_TOO_SMALL;
  }

  tftp_msg* msg = incoming;
  tftp_msg* resp = outgoing;

  // Decode opcode
  uint16_t opcode = ntohs(msg->opcode) & 0xff;
  xprintf("handle_msg opcode=%u length=%d\n", opcode, (int)inlen);

  // Set default timeout
  *timeout_ms = 1000 * session->timeout;

  // Reset timeout count
  session->consecutive_timeouts = 0;

  switch (opcode) {
    case OPCODE_RRQ:
      return tftp_handle_rrq(session, incoming, inlen, resp, outlen, timeout_ms, cookie);
    case OPCODE_WRQ:
      return tftp_handle_wrq(session, incoming, inlen, resp, outlen, timeout_ms, cookie);
    case OPCODE_DATA:
      return tftp_handle_data(session, incoming, inlen, resp, outlen, timeout_ms, cookie);
    case OPCODE_ACK:
      return tftp_handle_ack(session, incoming, inlen, resp, outlen, timeout_ms, cookie);
    case OPCODE_ERROR:
      return tftp_handle_error(session, incoming, inlen, resp, outlen, timeout_ms, cookie);
    case OPCODE_OACK:
      return tftp_handle_oack(session, incoming, inlen, resp, outlen, timeout_ms, cookie);
    default:
      xprintf("Unknown opcode\n");
      session->state = ERROR;
      return TFTP_ERR_INTERNAL;
  }
}

tftp_status tftp_prepare_data(tftp_session* session, void* outgoing, size_t* outlen, void* cookie) {
  tftp_data_msg* resp_data = outgoing;

  if ((session->block_number + session->window_index) * session->block_size > session->file_size) {
    *outlen = 0;
    return TFTP_TRANSFER_COMPLETED;
  }

  tftp_status ret = tx_data(session, resp_data, outlen, cookie);
  if (ret < 0) {
    set_error(session, TFTP_ERR_CODE_UNDEF, outgoing, outlen, "failure to transmit data");
  }
  return ret;
}

void tftp_session_set_max_timeouts(tftp_session* session, uint16_t max_timeouts) {
  session->max_timeouts = max_timeouts;
}

void tftp_session_set_opcode_prefix_use(tftp_session* session, bool enable) {
  session->use_opcode_prefix = enable;
}

tftp_status tftp_timeout(tftp_session* session, void* msg_buf, size_t* msg_len, size_t buf_sz,
                         void* file_cookie) {
  xprintf("Timeout\n");
  session->metrics.timeouts++;
  if (++session->consecutive_timeouts > session->max_timeouts) {
    return TFTP_ERR_TIMED_OUT;
  }
  // It's possible our previous transmission was dropped because of checksum errors.
  // Use a different opcode prefix when we resend.
  if (session->use_opcode_prefix) {
    session->opcode_prefix++;
  }
  if (session->state == REQ_SENT || session->state == REQ_RECEIVED) {
    // Resend previous message
    return TFTP_NO_ERROR;
  }
  *msg_len = buf_sz;
  if (session->direction == SEND_FILE) {
    // Reset back to the last-acknowledged block
    session->window_index = 0;
    return tftp_prepare_data(session, msg_buf, msg_len, file_cookie);
  } else {
    // ACK up to the last block read
    tftp_prepare_ack(session, msg_buf, msg_len);
    return TFTP_NO_ERROR;
  }
}

#define REPORT_ERR(opts, ...)                               \
  if (opts->err_msg) {                                      \
    snprintf(opts->err_msg, opts->err_msg_sz, __VA_ARGS__); \
  }

typedef struct {
  void* incoming;
  size_t in_buf_sz;
  void* outgoing;
  size_t out_buf_sz;
  char* err_msg;
  size_t err_msg_sz;
} tftp_msg_loop_opts;

static tftp_status tftp_msg_loop(tftp_session* session, void* transport_cookie, void* file_cookie,
                                 tftp_msg_loop_opts* opts, uint32_t timeout_ms) {
  tftp_status ret;
  size_t out_sz = 0;

  do {
    tftp_status send_status;
    int result = session->transport_interface.timeout_set(timeout_ms, transport_cookie);
    if (result < 0) {
      REPORT_ERR(opts, "failed during transport timeout set callback");
      return TFTP_ERR_INTERNAL;
    }

    bool pending = tftp_session_has_pending(session);
    int n = session->transport_interface.recv(opts->incoming, opts->in_buf_sz, !pending,
                                              transport_cookie);
    if (n == TFTP_ERR_TIMED_OUT) {
      if (pending) {
        out_sz = opts->out_buf_sz;
        ret = tftp_prepare_data(session, opts->outgoing, &out_sz, file_cookie);
        if (out_sz) {
          send_status = session->transport_interface.send(opts->outgoing, out_sz, transport_cookie);
          if (send_status != TFTP_NO_ERROR) {
            REPORT_ERR(opts, "failed during transport send callback");
            return send_status;
          }
        }
        if (ret < 0) {
          REPORT_ERR(opts, "failed to prepare data to send");
          return ret;
        }
      } else if (session->state != NONE) {
        ret = tftp_timeout(session, opts->outgoing, &out_sz, opts->out_buf_sz, file_cookie);
        if (ret == TFTP_ERR_TIMED_OUT) {
          REPORT_ERR(opts, "too many consecutive timeouts, aborting");
          return ret;
        }
        if (ret < 0) {
          REPORT_ERR(opts, "failed during timeout processing");
          return ret;
        }
        if (out_sz) {
          send_status = session->transport_interface.send(opts->outgoing, out_sz, transport_cookie);
          if (send_status != TFTP_NO_ERROR) {
            REPORT_ERR(opts, "failed during transport send callback");
            return n;
          }
        }
      }
      continue;
    } else if (n < 0) {
      REPORT_ERR(opts, "failed during transport recv callback");
      return n;
    }

    out_sz = opts->out_buf_sz;
    ret = tftp_process_msg(session, opts->incoming, n, opts->outgoing, &out_sz, &timeout_ms,
                           file_cookie);
    if (out_sz) {
      send_status = session->transport_interface.send(opts->outgoing, out_sz, transport_cookie);
      if (send_status != TFTP_NO_ERROR) {
        REPORT_ERR(opts, "failed during transport send callback");
        return send_status;
      }
    }
    if (ret < 0) {
      REPORT_ERR(opts, "failed to handle message");
      return ret;
    } else if (ret == TFTP_TRANSFER_COMPLETED) {
      return ret;
    }
  } while (1);
}

static tftp_status transfer_file(tftp_session* session, void* transport_cookie, void* file_cookie,
                                 tftp_file_direction xfer_direction, const char* local_filename,
                                 const char* remote_filename, tftp_request_opts* opts) {
  if (!opts || !opts->inbuf || !opts->inbuf_sz || !opts->outbuf || !opts->outbuf_sz) {
    return TFTP_ERR_INVALID_ARGS;
  }

  tftp_status status;

  ssize_t file_size = 0;
  if (xfer_direction == SEND_FILE) {
    file_size = session->file_interface.open_read(local_filename, session->timeout, file_cookie);
    if (file_size < 0) {
      REPORT_ERR(opts, "failed during file open callback");
      return file_size;
    }
  }

  tftp_mode mode = opts->mode ? *opts->mode : TFTP_DEFAULT_CLIENT_MODE;

  size_t out_sz = opts->outbuf_sz;
  uint32_t timeout_ms;
  status = tftp_generate_request(session, xfer_direction, local_filename, remote_filename, mode,
                                 file_size, opts->block_size, opts->timeout, opts->window_size,
                                 opts->outbuf, &out_sz, &timeout_ms);

  const char* xfer_direction_str = (xfer_direction == SEND_FILE) ? "write" : "read";
  if (status < 0) {
    REPORT_ERR(opts, "failed to generate %s request", xfer_direction_str);
    goto done;
  }
  if (!out_sz) {
    REPORT_ERR(opts, "no %s request generated", xfer_direction_str);
    status = TFTP_ERR_INTERNAL;
    goto done;
  }

  status = session->transport_interface.send(opts->outbuf, out_sz, transport_cookie);
  if (status != TFTP_NO_ERROR) {
    REPORT_ERR(opts, "failed during transport send callback");
    goto done;
  }

  tftp_msg_loop_opts msg_loop_opts = {.incoming = opts->inbuf,
                                      .in_buf_sz = opts->inbuf_sz,
                                      .outgoing = opts->outbuf,
                                      .out_buf_sz = opts->outbuf_sz,
                                      .err_msg = opts->err_msg,
                                      .err_msg_sz = opts->err_msg_sz};
  status = tftp_msg_loop(session, transport_cookie, file_cookie, &msg_loop_opts, timeout_ms);

done:
  if ((xfer_direction == SEND_FILE) || (session->state != NONE)) {
    if (session->file_interface.close) {
      session->file_interface.close(file_cookie);
    }
  }
  return status;
}

tftp_status tftp_push_file(tftp_session* session, void* transport_cookie, void* file_cookie,
                           const char* local_filename, const char* remote_filename,
                           tftp_request_opts* opts) {
  return transfer_file(session, transport_cookie, file_cookie, SEND_FILE, local_filename,
                       remote_filename, opts);
}

tftp_status tftp_pull_file(tftp_session* session, void* transport_cookie, void* file_cookie,
                           const char* local_filename, const char* remote_filename,
                           tftp_request_opts* opts) {
  return transfer_file(session, transport_cookie, file_cookie, RECV_FILE, local_filename,
                       remote_filename, opts);
}

tftp_status tftp_service_request(tftp_session* session, void* transport_cookie, void* file_cookie,
                                 tftp_handler_opts* opts) {
  if (!opts || !opts->inbuf || !opts->outbuf || !opts->outbuf_sz) {
    return TFTP_ERR_INVALID_ARGS;
  }
  tftp_msg_loop_opts msg_loop_opts = {.incoming = opts->inbuf,
                                      .in_buf_sz = opts->inbuf_sz,
                                      .outgoing = opts->outbuf,
                                      .out_buf_sz = *opts->outbuf_sz,
                                      .err_msg = opts->err_msg,
                                      .err_msg_sz = opts->err_msg_sz};
  uint32_t timeout_ms = session->timeout * 1000;
  tftp_status status =
      tftp_msg_loop(session, transport_cookie, file_cookie, &msg_loop_opts, timeout_ms);
  if ((session->state != NONE) && session->file_interface.close) {
    session->file_interface.close(file_cookie);
  }
  return status;
}

tftp_status tftp_handle_msg(tftp_session* session, void* transport_cookie, void* file_cookie,
                            tftp_handler_opts* opts) {
  if (!opts || !opts->inbuf || !opts->outbuf || !opts->outbuf_sz) {
    return TFTP_ERR_INVALID_ARGS;
  }
  uint32_t timeout_ms;
  tftp_status ret;
  ret = tftp_process_msg(session, opts->inbuf, opts->inbuf_sz, opts->outbuf, opts->outbuf_sz,
                         &timeout_ms, file_cookie);
  if (*opts->outbuf_sz) {
    tftp_status send_status =
        session->transport_interface.send(opts->outbuf, *opts->outbuf_sz, transport_cookie);
    if (send_status != TFTP_NO_ERROR) {
      REPORT_ERR(opts, "failed during transport send callback");
      return send_status;
    }
  }
  if (ret == TFTP_ERR_SHOULD_WAIT) {
    REPORT_ERR(opts, "request received, host is busy");
  } else if (ret < 0) {
    REPORT_ERR(opts, "handling tftp request failed (file might not exist)");
  } else if (ret == TFTP_TRANSFER_COMPLETED) {
    if (session->file_interface.close) {
      session->file_interface.close(file_cookie);
    }
  } else {
    ret = session->transport_interface.timeout_set(timeout_ms, transport_cookie);
    if (ret < 0) {
      REPORT_ERR(opts, "failed during transport timeout set callback");
    }
  }
  return ret;
}

tftp_status tftp_get_metrics(tftp_session* session, char* buf, size_t buf_sz) {
  snprintf(buf, buf_sz,
           "{"
           "\"inorderblks\": %u,"
           "\"oooblks\": %u,"
           "\"ack\": %u,"
           "\"nack\": %u,"
           "\"timeouts\": %u,"
           "\"sas\": %u,"
           "\"inorderbytes\": %" PRIu64 "}",
           session->metrics.inorder_blocks, session->metrics.outoforder_blocks,
           session->metrics.acks_sent, session->metrics.nacks_sent, session->metrics.timeouts,
           session->metrics.sas_events, session->metrics.inorder_bytes);
  if (strlen(buf) == buf_sz - 1) {
    return TFTP_ERR_BUFFER_TOO_SMALL;
  }
  return TFTP_NO_ERROR;
}

void tftp_clear_metrics(tftp_session* session) {
  memset(&session->metrics, 0, sizeof(session->metrics));
}
