/* client.c - Client TCP untuk server protokol baris
 *
 * Build:
 *   gcc -std=c11 -Wall -Wextra -pedantic -o client client.c protocol.c
 * Jalankan:
 *   ./client [host] [port]    # default 127.0.0.1:8080
 *
 * Setelah terhubung, ketik perintah lalu Enter. Contoh:
 *   PING
 *   ECHO hello world
 *   UPPER convert me
 *   TIME
 *   STATS
 *   QUIT
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "protocol.h"

/* Membaca satu baris dari socket. Mengembalikan jumlah byte termasuk newline
 * yang dibaca, 0 bila koneksi ditutup, -1 bila error. */
static ssize_t read_line(int fd, char *buf, size_t cap) {
    size_t total = 0;
    while (total < cap - 1) {
        char c;
        ssize_t n = read(fd, &c, 1);
        if (n <= 0) {
            return (n == 0) ? (ssize_t)total : -1;
        }
        buf[total++] = c;
        if (c == '\n') {
            break;
        }
    }
    buf[total] = '\0';
    return (ssize_t)total;
}

int main(int argc, char *argv[]) {
    const char *host = "127.0.0.1";
    int port = PROTO_PORT_DEFAULT;
    if (argc > 1) {
        host = argv[1];
    }
    if (argc > 2) {
        port = (int)strtol(argv[2], NULL, 10);
    }

    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd < 0) {
        perror("socket");
        return 1;
    }

    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons((uint16_t)port);
    if (inet_pton(AF_INET, host, &addr.sin_addr) != 1) {
        fprintf(stderr, "Alamat IP tidak valid: %s\n", host);
        close(fd);
        return 1;
    }

    printf("Menghubungkan ke %s:%d...\n", host, port);
    if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
        perror("connect");
        close(fd);
        return 1;
    }
    printf("Terhubung. Ketik perintah (QUIT untuk keluar).\n");

    char line[PROTO_BUFFER_MAX];
    char reply[PROTO_BUFFER_MAX];
    while (fgets(line, sizeof(line), stdin) != NULL) {
        /* Pastikan ada newline. */
        if (strchr(line, '\n') == NULL) {
            /* Baris terlalu panjang, flush stdin. */
            int c;
            while ((c = getchar()) != '\n' && c != EOF) {
                /* loop */
            }
        }
        size_t len = strlen(line);
        if (write(fd, line, len) != (ssize_t)len) {
            perror("write");
            break;
        }
        ssize_t r = read_line(fd, reply, sizeof(reply));
        if (r <= 0) {
            printf("Server menutup koneksi.\n");
            break;
        }
        fputs(reply, stdout);

        /* Berhenti bila server membalas kode BYE. */
        if (strncmp(reply, "410", 3) == 0) {
            break;
        }
    }

    close(fd);
    printf("Koneksi ditutup.\n");
    return 0;
}
