// 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.

#include <fbl/atomic.h>
#include <tftp/tftp.h>
#include <unittest/unittest.h>

#include <limits.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

// This test simulates a tftp file transfer by running two threads. Both the
// file and transport interfaces are implemented in memory buffers.

typedef enum { DIR_SEND, DIR_RECEIVE } xfer_dir_t;

struct test_params {
    xfer_dir_t direction;
    uint32_t filesz;
    uint16_t winsz;
    uint16_t blksz;
};

static uint8_t *src_file;
static uint8_t *dst_file;

/* FAUX FILES INTERFACE */

typedef struct {
    uint8_t* buf;
    char filename[PATH_MAX + 1];
    size_t filesz;
} file_info_t;

// Allocate our src and dst buffers, filling both with random values.
int initialize_files(struct test_params* tp) {
    src_file = reinterpret_cast<uint8_t*>(malloc(tp->filesz));
    dst_file = reinterpret_cast<uint8_t*>(malloc(tp->filesz));

    if (!src_file || !dst_file) {
        return 1;
    }

    int* src_as_ints = (int*)src_file;
    int* dst_as_ints = (int*)dst_file;

    size_t ndx;
    srand(0);
    for (ndx = 0; ndx < tp->filesz / sizeof(int); ndx++) {
        src_as_ints[ndx] = rand();
        dst_as_ints[ndx] = rand();
    }
    for (ndx = (tp->filesz / sizeof(int)) * sizeof(int);
         ndx < tp->filesz;
         ndx++) {
        src_file[ndx] = static_cast<uint8_t>(rand());
        dst_file[ndx] = static_cast<uint8_t>(rand());
    }

    return 0;
}

int compare_files(size_t filesz) {
    return memcmp(src_file, dst_file, filesz);
}

const char* file_get_filename(file_info_t* file_info) {
    return file_info->filename;
}

ssize_t file_open_read(const char* filename, void* file_cookie) {
    auto* file_info = reinterpret_cast<file_info_t*>(file_cookie);
    file_info->buf = src_file;
    strncpy(file_info->filename, filename, PATH_MAX);
    file_info->filename[PATH_MAX] = '\0';
    return file_info->filesz;
}

tftp_status file_open_write(const char* filename,
                            size_t size,
                            void* file_cookie) {
    auto* file_info = reinterpret_cast<file_info_t*>(file_cookie);
    file_info->buf = dst_file;
    file_info->filename[PATH_MAX] = '\0';
    strncpy(file_info->filename, filename, PATH_MAX);
    return TFTP_NO_ERROR;
}

// Every SHORT_READ_FREQ writes we will read a smaller amount instead, to verify behavior when
// a read operation returns a length less than the requested amount.
#define SHORT_READ_FREQ 10

tftp_status file_read(void* data, size_t* length, off_t offset,
                      void* file_cookie) {
    auto* file_info = reinterpret_cast<file_info_t*>(file_cookie);
    if ((size_t)offset > file_info->filesz) {
        // Something has gone wrong in libtftp
        return TFTP_ERR_INTERNAL;
    }
    if ((offset + *length) > file_info->filesz) {
        *length = file_info->filesz - offset;
    }
    static size_t read_count = 0;
    if (read_count++ % SHORT_READ_FREQ == 0) {
        *length /= 2;
    }
    memcpy(data, &file_info->buf[offset], *length);
    return TFTP_NO_ERROR;
}

// Every SHORT_WRITE_FREQ writes we will write a smaller amount instead, to verify behavior when
// a write operation returns a length less than the requested amount.
#define SHORT_WRITE_FREQ 10

tftp_status file_write(const void* data, size_t* length, off_t offset,
                       void* file_cookie) {
    auto* file_info = reinterpret_cast<file_info_t*>(file_cookie);
    if (((size_t)offset > file_info->filesz) || ((offset + *length) > file_info->filesz)) {
        // Something has gone wrong in libtftp
        return TFTP_ERR_INTERNAL;
    }
    static size_t write_count = 0;
    if (write_count++ % SHORT_WRITE_FREQ == 0) {
        *length /= 2;
    }
    memcpy(&file_info->buf[offset], data, *length);
    return TFTP_NO_ERROR;
}

void file_close(void* file_cookie) {
}

/* FAUX SOCKET INTERFACE */

#define FAKE_SOCK_BUF_SZ 65536
typedef struct {
    uint8_t buf[FAKE_SOCK_BUF_SZ];
    size_t size = FAKE_SOCK_BUF_SZ;
    fbl::atomic<size_t> read_ndx;
    fbl::atomic<size_t> write_ndx;
} fake_socket_t;
static fake_socket_t client_out_socket;
static fake_socket_t server_out_socket;

typedef struct {
    fake_socket_t* in_sock;
    fake_socket_t* out_sock;
} transport_info_t;

void clear_sockets(void) {
    client_out_socket.read_ndx.store(0);
    client_out_socket.write_ndx.store(0);
    server_out_socket.read_ndx.store(0);
    server_out_socket.write_ndx.store(0);
}

// Initialize "sockets" for either client or server.
void transport_init(transport_info_t* transport_info, bool is_server) {
    if (is_server) {
        transport_info->in_sock = &client_out_socket;
        transport_info->out_sock = &server_out_socket;
    } else {
        transport_info->in_sock = &server_out_socket;
        transport_info->out_sock = &client_out_socket;
    }
}

// Write to our circular message buffer.
void write_to_buf(fake_socket_t* sock, void* data, size_t size) {
    uint8_t* in_buf = reinterpret_cast<uint8_t*>(data);
    uint8_t* out_buf = sock->buf;
    size_t curr_offset = sock->write_ndx.load() % sock->size;
    if (curr_offset + size <= sock->size) {
        memcpy(&out_buf[curr_offset], in_buf, size);
    } else {
        size_t first_size = sock->size - curr_offset;
        size_t second_size = size - first_size;
        memcpy(out_buf + curr_offset, in_buf, first_size);
        memcpy(out_buf, in_buf + first_size, second_size);
    }
    sock->write_ndx.fetch_add(size);
}

// Send a message. Note that the buffer's read_ndx and write_ndx don't wrap,
// which makes it easier to recognize underflow.
tftp_status transport_send(void* data, size_t len, void* transport_cookie) {
    auto* transport_info = reinterpret_cast<transport_info_t*>(transport_cookie);
    fake_socket_t* sock = transport_info->out_sock;
    while ((sock->write_ndx.load() + sizeof(len) + len - sock->read_ndx.load())
           > sock->size) {
        // Wait for the other thread to catch up
        usleep(10);
    }
    write_to_buf(sock, &len, sizeof(len));
    write_to_buf(sock, data, len);
    return TFTP_NO_ERROR;
}

// Read from our circular message buffer. If |move_ptr| is false, just peeks at
// the data (reads without updating the read pointer).
void read_from_buf(fake_socket_t* sock, void* data, size_t size,
                   bool move_ptr) {
    uint8_t* in_buf = sock->buf;
    uint8_t* out_buf = reinterpret_cast<uint8_t*>(data);
    size_t curr_offset = sock->read_ndx.load() % sock->size;
    if (curr_offset + size <= sock->size) {
        memcpy(out_buf, &in_buf[curr_offset], size);
    } else {
        size_t first_size = sock->size - curr_offset;
        size_t second_size = size - first_size;
        memcpy(out_buf, in_buf + curr_offset, first_size);
        memcpy(out_buf + first_size, in_buf, second_size);
    }
    if (move_ptr) {
        sock->read_ndx.fetch_add(size);
    }
}

// Receive a message. Note that the buffer's read_ndx and write_ndx don't
// wrap, which makes it easier to recognize underflow.
int transport_recv(void* data, size_t len, bool block, void* transport_cookie) {
    auto* transport_info = reinterpret_cast<transport_info_t*>(transport_cookie);
    if (block) {
        while ((transport_info->in_sock->read_ndx.load() + sizeof(size_t)) >=
               transport_info->in_sock->write_ndx.load()) {
            usleep(10);
        }
    } else if ((transport_info->in_sock->read_ndx.load() + sizeof(size_t)) >=
               transport_info->in_sock->write_ndx.load()) {
        return TFTP_ERR_TIMED_OUT;
    }
    size_t block_len;
    read_from_buf(transport_info->in_sock, &block_len, sizeof(block_len),
                  false);
    if (block_len > len) {
        return TFTP_ERR_BUFFER_TOO_SMALL;
    }
    transport_info->in_sock->read_ndx.fetch_add(sizeof(block_len));
    read_from_buf(transport_info->in_sock, data, block_len, true);
    return static_cast<int>(block_len);
}

int transport_timeout_set(uint32_t timeout_ms, void* transport_cookie) {
    return 0;
}

/// SEND THREAD

bool run_client_test(struct test_params* tp) {
    BEGIN_HELPER;

    // Configure TFTP session
    tftp_session* session;
    size_t session_size = tftp_sizeof_session();
    void* session_buf = malloc(session_size);
    ASSERT_NONNULL(session_buf, "memory allocation failed");

    tftp_status status = tftp_init(&session, session_buf, session_size);
    ASSERT_EQ(status, TFTP_NO_ERROR, "unable to initialize a tftp session");

    // Configure file interface
    file_info_t file_info;
    file_info.filesz = tp->filesz;
    tftp_file_interface file_callbacks = { file_open_read,
                                           file_open_write,
                                           file_read,
                                           file_write,
                                           file_close };
    status = tftp_session_set_file_interface(session, &file_callbacks);
    ASSERT_EQ(status, TFTP_NO_ERROR, "could not set file interface");

    // Configure transport interface
    transport_info_t transport_info;
    transport_init(&transport_info, false);

    tftp_transport_interface transport_callbacks = { transport_send,
                                                     transport_recv,
                                                     transport_timeout_set };
    status = tftp_session_set_transport_interface(session,
                                                  &transport_callbacks);
    ASSERT_EQ(status, TFTP_NO_ERROR, "could not set transport interface");

    // Allocate intermediate buffers
    size_t buf_sz = tp->blksz > PATH_MAX ?
                    tp->blksz + 2 : PATH_MAX + 2;
    char* msg_in_buf = reinterpret_cast<char*>(malloc(buf_sz));
    ASSERT_NONNULL(msg_in_buf, "memory allocation failure");
    char* msg_out_buf = reinterpret_cast<char*>(malloc(buf_sz));
    ASSERT_NONNULL(msg_out_buf, "memory allocation failure");

    char err_msg_buf[128];

    // Set our preferred transport options
    tftp_set_options(session, &tp->blksz, NULL, &tp->winsz);

    tftp_request_opts opts = {};
    opts.inbuf = msg_in_buf;
    opts.inbuf_sz = buf_sz;
    opts.outbuf = msg_out_buf;
    opts.outbuf_sz = buf_sz;
    opts.err_msg = err_msg_buf;
    opts.err_msg_sz = sizeof(err_msg_buf);

    if (tp->direction == DIR_SEND) {
        status = tftp_push_file(session, &transport_info, &file_info, "abc.txt",
                                "xyz.txt", &opts);
        EXPECT_GE(status, 0, "failed to send file");
    } else {
        status = tftp_pull_file(session, &transport_info, &file_info, "abc.txt",
                                "xyz.txt", &opts);
        EXPECT_GE(status, 0, "failed to receive file");
    }

    free(session);
    END_HELPER;
}

void* tftp_client_main(void* arg) {
    auto* tp = reinterpret_cast<test_params*>(arg);
    run_client_test(tp);
    pthread_exit(NULL);
}

/// RECV THREAD

bool run_server_test(struct test_params* tp) {
    BEGIN_HELPER;

    // Configure TFTP session
    tftp_session* session;
    size_t session_size = tftp_sizeof_session();
    void* session_buf = malloc(session_size);
    ASSERT_NONNULL(session_buf, "memory allocation failed");

    tftp_status status = tftp_init(&session, session_buf, session_size);
    ASSERT_EQ(status, TFTP_NO_ERROR, "unable to initiate a tftp session");

    // Configure file interface
    file_info_t file_info;
    file_info.filesz = tp->filesz;
    tftp_file_interface file_callbacks = { file_open_read,
                                           file_open_write,
                                           file_read,
                                           file_write,
                                           file_close };
    status = tftp_session_set_file_interface(session, &file_callbacks);
    ASSERT_EQ(status, TFTP_NO_ERROR, "could not set file interface");

    // Configure transport interface
    transport_info_t transport_info;
    transport_init(&transport_info, true);
    tftp_transport_interface transport_callbacks = { transport_send,
                                                     transport_recv,
                                                     transport_timeout_set };
    status = tftp_session_set_transport_interface(session,
                                                  &transport_callbacks);
    ASSERT_EQ(status, TFTP_NO_ERROR, "could not set transport interface");

    // Allocate intermediate buffers
    size_t buf_sz = tp->blksz > PATH_MAX ?
                    tp->blksz + 2 : PATH_MAX + 2;
    char* msg_in_buf = reinterpret_cast<char*>(malloc(buf_sz));
    ASSERT_NONNULL(msg_in_buf, "memory allocation failure");
    char* msg_out_buf = reinterpret_cast<char*>(malloc(buf_sz));
    ASSERT_NONNULL(msg_out_buf, "memory allocation failure");

    char err_msg_buf[128];
    tftp_handler_opts opts = { .inbuf = msg_in_buf,
                               .inbuf_sz = buf_sz,
                               .outbuf = msg_out_buf,
                               .outbuf_sz = &buf_sz,
                               .err_msg = err_msg_buf,
                               .err_msg_sz = sizeof(err_msg_buf) };
    do {
        status = tftp_service_request(session, &transport_info, &file_info,
                                      &opts);
    } while (status == TFTP_NO_ERROR);
    EXPECT_EQ(status, TFTP_TRANSFER_COMPLETED, "failed to receive file");
    free(session);
    END_HELPER;
}

void* tftp_server_main(void* arg) {
    auto* tp = reinterpret_cast<test_params*>(arg);
    run_server_test(tp);
    pthread_exit(NULL);
}

bool run_one_test(struct test_params* tp) {
    BEGIN_TEST;
    int init_result = initialize_files(tp);
    ASSERT_EQ(init_result, 0, "failure to initialize state");

    clear_sockets();

    pthread_t client_thread, server_thread;
    pthread_create(&client_thread, NULL, tftp_client_main, tp);
    pthread_create(&server_thread, NULL, tftp_server_main, tp);

    pthread_join(client_thread, NULL);
    pthread_join(server_thread, NULL);

    int compare_result = compare_files(tp->filesz);
    EXPECT_EQ(compare_result, 0, "output file mismatch");
    END_TEST;
}

bool test_tftp_send_file(void) {
    struct test_params tp = {.direction = DIR_SEND, .filesz = 1000000, .winsz = 20, .blksz = 1000};
    return run_one_test(&tp);
}

bool test_tftp_send_file_wrapping_block_count(void) {
    // Wraps block count 4 times
    struct test_params tp = {.direction = DIR_SEND, .filesz = 2100000, .winsz = 9999, .blksz = 8};
    return run_one_test(&tp);
}

bool test_tftp_send_file_lg_window(void) {
    // Make sure that a window size > 255 works properly
    struct test_params tp = {.direction = DIR_SEND, .filesz = 1000000, .winsz = 1024,
                             .blksz = 1024};
    return run_one_test(&tp);
}

bool test_tftp_receive_file(void) {
    struct test_params tp = {.direction = DIR_RECEIVE, .filesz = 1000000, .winsz = 20,
                             .blksz = 1000};
    return run_one_test(&tp);
}

bool test_tftp_receive_file_wrapping_block_count(void) {
    // Wraps block count 4 times
    struct test_params tp = {.direction = DIR_RECEIVE, .filesz = 2100000, .winsz = 8192,
                             .blksz = 8};
    return run_one_test(&tp);
}

bool test_tftp_receive_file_lg_window(void) {
    // Make sure that a window size > 255 works properly
    struct test_params tp = {.direction = DIR_RECEIVE, .filesz = 1000000, .winsz = 1024,
                             .blksz = 1024};
    return run_one_test(&tp);
}

BEGIN_TEST_CASE(tftp_transfer_file)
RUN_TEST(test_tftp_send_file)
RUN_TEST(test_tftp_send_file_wrapping_block_count)
RUN_TEST(test_tftp_send_file_lg_window)
RUN_TEST(test_tftp_receive_file)
RUN_TEST(test_tftp_receive_file_wrapping_block_count)
RUN_TEST(test_tftp_receive_file_lg_window)
END_TEST_CASE(tftp_transfer_file)

