// 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);
}

int 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,
                                                      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, 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,
                                               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,
                              uint32_t* timeout_ms,
                              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,
                         uint32_t* timeout_ms,
                         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, timeout_ms, 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,
                                        &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 prepare data to send");
                    return ret;
                }
            } else if (session->state != NONE) {
                ret = tftp_timeout(session,
                                   opts->outgoing,
                                   &out_sz,
                                   opts->out_buf_sz,
                                   &timeout_ms,
                                   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, 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));
}
