/* parser.c -- parsing dan agregasi kolom CSV. */

#include "parser.h"

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

ParserStatus parser_ke_double(const char *s, double *out) {
    if (s == 0 || out == 0) return PARSER_ERR_KONVERSI;
    /* Skip whitespace di awal. */
    while (*s == ' ' || *s == '\t') s++;
    if (*s == '\0') return PARSER_ERR_KONVERSI;

    char *sisa = 0;
    double v = strtod(s, &sisa);
    if (sisa == s) return PARSER_ERR_KONVERSI;
    *out = v;
    return PARSER_OK;
}

int parser_valid_angka(const char *s) {
    double dummy;
    return parser_ke_double(s, &dummy) == PARSER_OK;
}

ParserStatus parser_statistik_kolom(const CsvTable *tabel,
                                      int kolom,
                                      int skip_header,
                                      Statistik *stat) {
    if (tabel == 0 || stat == 0) return PARSER_ERR_TIDAK_ADA_DATA;
    if (kolom < 0 || kolom >= CSV_MAKS_FIELD) return PARSER_ERR_KOLOM_INVALID;

    /* Inisialisasi statistik. */
    stat->jumlah = 0;
    stat->jumlah_nilai = 0.0;
    stat->minimum = 0.0;
    stat->maksimum = 0.0;
    stat->rata_rata = 0.0;

    int mulai = skip_header ? 1 : 0;
    int ada_data = 0;

    for (int i = mulai; i < tabel->jumlah_baris; i++) {
        const CsvRow *row = &tabel->baris[i];
        if (kolom >= row->jumlah_field) {
            return PARSER_ERR_KOLOM_INVALID;
        }
        double v;
        ParserStatus ps = parser_ke_double(row->fields[kolom], &v);
        if (ps != PARSER_OK) {
            return PARSER_ERR_KONVERSI;
        }
        if (!ada_data) {
            stat->minimum = v;
            stat->maksimum = v;
            ada_data = 1;
        } else {
            if (v < stat->minimum) stat->minimum = v;
            if (v > stat->maksimum) stat->maksimum = v;
        }
        stat->jumlah_nilai += v;
        stat->jumlah++;
    }

    if (!ada_data) return PARSER_ERR_TIDAK_ADA_DATA;
    stat->rata_rata = stat->jumlah_nilai / stat->jumlah;
    return PARSER_OK;
}

void parser_cetak_statistik(const Statistik *stat, const char *nama_kolom, FILE *out) {
    if (stat == 0 || out == 0) return;
    fprintf(out, "Statistik kolom '%s':\n", nama_kolom ? nama_kolom : "?");
    fprintf(out, "  Jumlah data : %d\n", stat->jumlah);
    fprintf(out, "  Total       : %g\n", stat->jumlah_nilai);
    fprintf(out, "  Minimum     : %g\n", stat->minimum);
    fprintf(out, "  Maksimum    : %g\n", stat->maksimum);
    fprintf(out, "  Rata-rata   : %g\n", stat->rata_rata);
}
