#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netdb.h>
#include <net.h>

#define BUFSIZE 4096 - 8

int SEQ_NR = 1;
int LAST_ACKED = 0;

void send_with_ack(int sock, uint8_t *data, int length)
{
    uc_header header = { .sequence_nr = SEQ_NR,
                         .flags = 1,
                         .size = length };

    static uint8_t recvbuf[BUFSIZE] = {0};

    do
    {
        send(sock, &header, sizeof header, 0);
        send(sock, data, length, 0);
        header.flags = 1 | 2;
receive:
        if (recv(sock, recvbuf, BUFSIZE, 0) == -1)
        {
            if (errno == EINTR)
            {
                goto receive;
            }
        } else {
            uc_header srv_header = get_header(recvbuf);
            LAST_ACKED = srv_header.sequence_nr;
        }
    } while (LAST_ACKED < header.sequence_nr);

    SEQ_NR++;
}

int main(int argc, char* argv[])
{
    if (argc < 2)
    {
        fprintf(stderr, "Usage: %s <addr> [port]\n", argv[0]);
        exit(1);
    }

    const char* port = "16064";
    const char* addr = argv[1];

    if (argc > 2)
    {
        port = argv[2];
    }

    int sock = uc_client_socket(addr, port);

    uint8_t buf[BUFSIZE];
    int len = 0;

    while ((len = read(STDIN_FILENO, buf, BUFSIZE)) != 0)
    {
        send_with_ack(sock, buf, len);
    }

    return 0;
}
