/*
  Manifest runner.

  Input CSV format:
    scenario_id,source_csv,steps,out_csv

  Lines beginning with # are ignored.  If steps is blank/0, 720 is used.
  If out_csv is blank, output/SCENARIO_ID_forecast66.csv is used.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/stat.h>

#ifdef _WIN32
#include <direct.h>
#define MKDIR(path) _mkdir(path)
#else
#define MKDIR(path) mkdir(path, 0775)
#endif

#include "tsunami_core.h"

static char *trim(char *s) {
    while (*s && isspace((unsigned char)*s)) s++;
    char *e = s + strlen(s);
    while (e > s && isspace((unsigned char)e[-1])) *--e = '\0';
    return s;
}

static int split_csv_simple(char *line, char **fields, int max_fields) {
    int n = 0;
    char *p = line;
    while (n < max_fields) {
        fields[n++] = trim(p);
        char *comma = strchr(p, ',');
        if (!comma) break;
        *comma = '\0';
        p = comma + 1;
    }
    return n;
}

static int run_one(const GridData *grid, const char *scenario_id, const char *source_path, int steps, const char *out_path) {
    SourceList sources = {0};
    if (!load_sources_csv(&sources, source_path)) {
        fprintf(stderr, "FAILED source load: %s\n", source_path);
        return 0;
    }

    Simulation sim = create_simulation(grid);
    reset_simulation(grid, &sim);
    apply_sources_to_simulation(grid, &sim, &sources);

    for (int step = 0; step < steps; ++step) {
        int time_s = step * DEFAULT_DT_SECONDS;
        simulate_one_step(grid, &sim, time_s);
        update_station_stats(grid, &sim, time_s);
    }

    write_forecast_zone_compact_file(out_path, grid, &sim, scenario_id, source_path,
                                     steps * DEFAULT_DT_SECONDS, 0.05f);
    fprintf(stderr, "OK %s -> %s\n", scenario_id, out_path);

    free_simulation(&sim);
    source_list_free(&sources);
    return 1;
}

int main(int argc, char **argv) {
    if (argc < 3) {
        fprintf(stderr, "Usage: %s tsunami_data.bin manifest.csv\n", argv[0]);
        return 2;
    }
    const char *data_path = argv[1];
    const char *manifest_path = argv[2];

    MKDIR("output");

    GridData grid = load_grid_data(data_path);
    rebuild_solid_mask(&grid, DEFAULT_COAST_GUARD_CELLS);
    if (load_land_override_csv(&grid, "coast_override.csv")) {
        rebuild_solid_mask(&grid, DEFAULT_COAST_GUARD_CELLS);
    }

    FILE *fp = fopen(manifest_path, "r");
    if (!fp) {
        fprintf(stderr, "Cannot open manifest: %s\n", manifest_path);
        free_grid_data(&grid);
        return 1;
    }

    char line[2048];
    int line_no = 0, ok = 0, fail = 0;
    while (fgets(line, sizeof(line), fp)) {
        line_no++;
        char *p = trim(line);
        if (*p == '\0' || *p == '#') continue;
        if (line_no == 1 && strstr(p, "scenario_id") != NULL) continue;
        char *fields[4] = {0};
        int n = split_csv_simple(p, fields, 4);
        if (n < 2) continue;
        const char *scenario_id = fields[0];
        const char *source_path = fields[1];
        int steps = (n >= 3 && fields[2] && fields[2][0]) ? atoi(fields[2]) : 720;
        if (steps <= 0) steps = 720;
        char out_path[1024];
        if (n >= 4 && fields[3] && fields[3][0]) {
            snprintf(out_path, sizeof(out_path), "%s", fields[3]);
        } else {
            snprintf(out_path, sizeof(out_path), "output/%s_forecast66.csv", scenario_id && scenario_id[0] ? scenario_id : "scenario");
        }
        if (run_one(&grid, scenario_id, source_path, steps, out_path)) ok++; else fail++;
    }
    fclose(fp);
    free_grid_data(&grid);
    fprintf(stderr, "Done. ok=%d fail=%d\n", ok, fail);
    return fail ? 1 : 0;
}
