"""Fetch the M>=6.0 global earthquake catalogue this study runs on.

USGS ComCat, FDSN event web service, no key. One request per UTC year so that
no single request approaches the 20,000-row cap and a failure costs one year.
Resumable: a year already present in the output file is skipped.

    python fetch.py

Writes ~/data/quake-moon/comcat_m60_1973_2025.csv (raw, not committed; it is
about 1.5 MB and re-downloadable from the URL printed in the header).
Source: https://earthquake.usgs.gov/fdsnws/event/1/
"""

import csv
import io
import pathlib
import sys
import time

import requests

OUT = pathlib.Path.home() / "data" / "quake-moon"
BASE = "https://earthquake.usgs.gov/fdsnws/event/1/query"
UA = {"User-Agent": "untilnextsession.com research (vesper@untilnextsession.com)"}
YEARS = range(1973, 2026)
MINMAG = 6.0
COLS = ["time", "latitude", "longitude", "depth", "mag", "magType", "id", "place"]


def year(y):
    params = {
        "format": "csv",
        "eventtype": "earthquake",
        "minmagnitude": MINMAG,
        "starttime": f"{y}-01-01T00:00:00",
        "endtime": f"{y}-12-31T23:59:59",
        "orderby": "time-asc",
    }
    for attempt in range(6):
        try:
            r = requests.get(BASE, params=params, headers=UA, timeout=300)
            if r.status_code == 200:
                rows = list(csv.DictReader(io.StringIO(r.text)))
                return [{c: row.get(c, "") for c in COLS} for row in rows]
            print("http", r.status_code, y, flush=True)
        except requests.RequestException as e:
            print("error", e, y, flush=True)
        time.sleep(10 * (attempt + 1))
    raise RuntimeError(f"gave up on {y}")


def main():
    OUT.mkdir(parents=True, exist_ok=True)
    path = OUT / "comcat_m60_1973_2025.csv"
    have = set()
    if path.exists():
        with path.open() as f:
            have = {row["time"][:4] for row in csv.DictReader(f)}
    new = not path.exists()
    with path.open("a", newline="") as f:
        w = csv.DictWriter(f, fieldnames=COLS)
        if new:
            w.writeheader()
        for y in YEARS:
            if str(y) in have:
                continue
            rows = year(y)
            w.writerows(rows)
            f.flush()
            print(y, len(rows), flush=True)
            time.sleep(1)
    with path.open() as f:
        n = sum(1 for _ in csv.DictReader(f))
    print("total", n, path, file=sys.stderr)


if __name__ == "__main__":
    main()
