// El servicio de conteo.
#define _POSIX_C_SOURCE 200809L

#include "wc_service.h"

#include "io_util.h"

#include <ctype.h>
#include <errno.h>
#include <inttypes.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>

void wc_update(struct wc_counts *counts, const char *buf, size_t n) {
    for (size_t i = 0; i < n; i++) {
        unsigned char c = (unsigned char)buf[i];
        counts->bytes++;
        if (c == '\n') {
            counts->lines++;
        }
        if (isspace(c)) {
            counts->in_word = false;
        } else if (!counts->in_word) {
            counts->in_word = true;
            counts->words++;
        }
    }
}

int wc_serve_client(int conn) {
    struct wc_counts counts = {0};
    char buf[4096];
    for (;;) {
        ssize_t n = recv(conn, buf, sizeof buf, 0);
        if (n == -1) {
            if (errno == EINTR) {
                continue;
            }
            perror("recv");
            return -1;
        }
        if (n == 0) {
            break;  // fin del stream: el cliente ya no enviará más
        }
        wc_update(&counts, buf, (size_t)n);
    }
    char reply[128];
    int len = snprintf(reply, sizeof reply,
                       "bytes=%" PRIu64 " words=%" PRIu64 " lines=%" PRIu64 "\n",
                       counts.bytes, counts.words, counts.lines);
    return send_all(conn, reply, (size_t)len);
}
