/* csv_reader.c -- pembaca file CSV sederhana. */

#include "csv_reader.h"

#include <stdio.h>
#include <string.h>

/* Memisahkan satu baris teks menjadi field-field dengan pemisah koma.
 * Menulis hasil ke row->fields dan mengisi row->jumlah_field.
 * Mengembalikan jumlah field yang berhasil diparse.
 */
static int pisahkan_baris(const char *line, CsvRow *row) {
    if (row == 0) return 0;
    row->jumlah_field = 0;
    int i = 0;          /* indeks field */
    int j = 0;          /* indeks char di dalam field */

    while (line[i] != '\0' && row->jumlah_field < CSV_MAKS_FIELD) {
        char c = line[i];
        if (c == ',') {
            row->fields[row->jumlah_field][j] = '\0';
            row->jumlah_field++;
            j = 0;
        } else if (c != '\n' && c != '\r') {
            if (j < CSV_MAKS_PANJANG_FIELD - 1) {
                row->fields[row->jumlah_field][j] = c;
                j++;
            }
        }
        i++;
    }
    /* Tutup field terakhir. */
    row->fields[row->jumlah_field][j] = '\0';
    row->jumlah_field++;
    return row->jumlah_field;
}

CsvStatus csv_baca(const char *path, CsvTable *tabel) {
    if (path == 0 || tabel == 0) return CSV_ERR_BUKA_FILE;
    FILE *f = fopen(path, "r");
    if (f == 0) return CSV_ERR_BUKA_FILE;

    tabel->jumlah_baris = 0;
    char baris[512];

    while (fgets(baris, sizeof(baris), f) != 0
           && tabel->jumlah_baris < CSV_MAKS_BARIS) {
        /* Skip baris kosong. */
        if (baris[0] == '\n' || baris[0] == '\r' || baris[0] == '\0') {
            continue;
        }
        CsvRow *row = &tabel->baris[tabel->jumlah_baris];
        int n = pisahkan_baris(baris, row);
        if (n == 0) {
            fclose(f);
            return CSV_ERR_FORMAT;
        }
        tabel->jumlah_baris++;
    }

    fclose(f);
    if (tabel->jumlah_baris == 0) {
        return CSV_ERR_FORMAT;
    }
    return CSV_OK;
}

void csv_tampilkan(const CsvTable *tabel, FILE *out) {
    if (tabel == 0 || out == 0) return;
    for (int i = 0; i < tabel->jumlah_baris; i++) {
        const CsvRow *r = &tabel->baris[i];
        for (int j = 0; j < r->jumlah_field; j++) {
            fprintf(out, "%s", r->fields[j]);
            if (j < r->jumlah_field - 1) fprintf(out, " | ");
        }
        fprintf(out, "\n");
    }
}
