/*
  Batch extractor for the tsunami GUI model.

  It runs one source CSV without opening the Win32 GUI and writes a 66-zone
  compact CSV containing only:
    - first wave arrival time (fixed 5 cm threshold used by the core)
    - maximum positive tsunami height

  Usage:
    tsunami_batch_forecast66.exe tsunami_data.bin source_points.csv out.csv [steps] [scenario_id]

  steps: model steps, each step is DEFAULT_DT_SECONDS (=15 s). 1440 = 6 hours.
*/

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

#include "tsunami_core.h"

static void usage(const char *exe) {
    fprintf(stderr,
            "Usage: %s tsunami_data.bin source_points.csv out_forecast66.csv [steps] [scenario_id]\n"
            "  steps default: 720 (6 hours with dt=30 s)\n"
            "  arrival threshold: fixed 0.05 m in current core\n",
            exe);
}

int main(int argc, char **argv) {
    if (argc < 4) {
        usage(argv[0]);
        return 2;
    }

    const char *data_path = argv[1];
    const char *source_path = argv[2];
    const char *out_path = argv[3];
    int steps = 720;
    const char *scenario_id = "";

    if (argc >= 5) {
        steps = atoi(argv[4]);
        if (steps <= 0) steps = 720;
    }
    if (argc >= 6) scenario_id = argv[5];

    fprintf(stderr, "Loading grid: %s\n", data_path);
    GridData grid = load_grid_data(data_path);
    rebuild_solid_mask(&grid, DEFAULT_COAST_GUARD_CELLS);

    /* Match the GUI behavior: load default coastline / land-sea correction when present. */
    if (load_land_override_csv(&grid, "coast_override.csv")) {
        rebuild_solid_mask(&grid, DEFAULT_COAST_GUARD_CELLS);
        fprintf(stderr, "Loaded coast_override.csv corrections.\n");
    }

    SourceList sources = {0};
    if (!load_sources_csv(&sources, source_path)) {
        fprintf(stderr, "Failed to load source CSV: %s\n", source_path);
        free_grid_data(&grid);
        return 1;
    }
    fprintf(stderr, "Loaded %zu source cells.\n", sources.count);

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

    clock_t t0 = clock();
    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);
        if ((step + 1) % 100 == 0 || step + 1 == steps) {
            fprintf(stderr, "step %d/%d  model_time=%.2f h\r", step + 1, steps,
                    (step + 1) * DEFAULT_DT_SECONDS / 3600.0);
            fflush(stderr);
        }
    }
    fprintf(stderr, "\n");

    int run_time_s = steps * DEFAULT_DT_SECONDS;
    write_forecast_zone_compact_file(out_path, &grid, &sim, scenario_id, source_path, run_time_s, 0.05f);
    fprintf(stderr, "Wrote: %s\n", out_path);

    clock_t t1 = clock();
    double elapsed = (double)(t1 - t0) / (double)CLOCKS_PER_SEC;
    fprintf(stderr, "Elapsed CPU time: %.2f s\n", elapsed);

    free_simulation(&sim);
    source_list_free(&sources);
    free_grid_data(&grid);
    return 0;
}
