#!/usr/bin/env python3
"""Perform start/middle/tail 64-KiB range checks per repository/format."""

from __future__ import annotations

import csv
import hashlib
import json
import re
import sys
import time
import urllib.request
from datetime import datetime, timezone
from pathlib import Path


DATE = "2026-08-01"
CHUNK = 64 * 1024
USER_AGENT = "LGASieve-public-WES-multirange/1.0"


def truthy(value: object) -> bool:
    return str(value).strip().lower() in {"true", "1", "yes"}


def integer(value: object) -> int | None:
    text = str(value or "").strip()
    return int(text) if text.isdigit() else None


def probe(url: str, start: int, end: int, total: int) -> dict[str, object]:
    last_error = ""
    last_result: dict[str, object] | None = None
    for attempt in range(5):
        try:
            request = urllib.request.Request(
                url,
                headers={
                    "Range": f"bytes={start}-{end}",
                    "User-Agent": USER_AGENT,
                    "Accept": "*/*",
                    "Accept-Encoding": "identity",
                },
            )
            with urllib.request.urlopen(request, timeout=90) as response:
                status = int(getattr(response, "status", 0) or response.getcode())
                body = response.read(CHUNK + 1)
                content_range = response.headers.get("Content-Range", "")
                match = re.fullmatch(r"bytes (\d+)-(\d+)/(\d+)", content_range)
                exact_content_range = bool(
                    match
                    and int(match.group(1)) == start
                    and int(match.group(2)) == end
                    and int(match.group(3)) == total
                )
                expected_payload = end - start + 1
                result: dict[str, object] = {
                    "http_status": status,
                    "content_range": content_range,
                    "bytes_received": len(body),
                    "expected_payload_bytes": expected_payload,
                    "range_result": "HTTP_206_range_honored" if status == 206 else "HTTP_200_range_ignored" if status == 200 else "unexpected_status",
                    "strict_success": status == 206 and exact_content_range and len(body) == expected_payload,
                    "exact_content_range": exact_content_range,
                    "payload_sha256": hashlib.sha256(body).hexdigest(),
                    "payload_first_16_bytes_hex": body[:16].hex(),
                    "content_type": response.headers.get("Content-Type", ""),
                    "attempts": attempt + 1,
                    "error": "",
                }
                if result["strict_success"]:
                    return result
                last_result = result
                last_error = "Non-strict response: status/content-range/payload-length mismatch"
        except Exception as exc:
            last_error = f"{type(exc).__name__}: {exc}"
        if attempt < 4:
            time.sleep(1.0 * (2**attempt))
    if last_result is not None:
        last_result["attempts"] = 5
        last_result["error"] = last_error
        return last_result
    return {
        "http_status": "",
        "content_range": "",
        "bytes_received": 0,
        "expected_payload_bytes": end - start + 1,
        "range_result": "probe_failed",
        "strict_success": False,
        "exact_content_range": False,
        "payload_sha256": "",
        "payload_first_16_bytes_hex": "",
        "content_type": "",
        "attempts": 5,
        "error": last_error,
    }


def main() -> int:
    if len(sys.argv) != 2:
        raise SystemExit("usage: multirange_spotcheck_public_wes.py FINAL_INVENTORY_CSV")
    source = Path(sys.argv[1])
    with source.open("r", encoding="utf-8", newline="") as fh:
        rows = [row for row in csv.DictReader(fh) if truthy(row.get("verified_downloadable"))]

    selected: dict[tuple[str, str], dict[str, str]] = {}
    for row in rows:
        size = integer(row.get("alignment_bytes"))
        if not size or size < CHUNK:
            continue
        key = (row["repository"], row["alignment_format"])
        current = selected.get(key)
        current_size = integer(current.get("alignment_bytes")) if current else None
        # Prefer a middle-sized file over pathological tiny files; the exact
        # choice is deterministic and recorded in the output.
        if current is None or abs(size - 8 * 1024**3) < abs((current_size or 0) - 8 * 1024**3):
            selected[key] = row

    results: list[dict[str, object]] = []
    for key in sorted(selected):
        row = selected[key]
        total = integer(row["alignment_bytes"])
        assert total is not None
        starts = {
            "start": 0,
            "middle": max(0, (total - CHUNK) // 2),
            "tail": max(0, total - CHUNK),
        }
        for position, start in starts.items():
            end = min(total - 1, start + CHUNK - 1)
            outcome = probe(row["alignment_url"], start, end, total)
            results.append(
                {
                    "repository": row["repository"],
                    "alignment_format": row["alignment_format"],
                    "collection": row.get("collection", ""),
                    "run_accession": row.get("run_accession", ""),
                    "sample_id": row.get("sample_id", ""),
                    "alignment_url": row["alignment_url"],
                    "alignment_bytes": total,
                    "position": position,
                    "requested_start": start,
                    "requested_end": end,
                    **outcome,
                }
            )

    fields = list(results[0]) if results else []
    output = source.with_name(f"public_wes_multirange_spotcheck_{DATE}.csv")
    with output.open("w", encoding="utf-8", newline="") as fh:
        writer = csv.DictWriter(fh, fieldnames=fields)
        writer.writeheader()
        writer.writerows(results)
    start_rows = [row for row in results if row["position"] == "start"]
    signature_checks = [
        {
            "repository": row["repository"],
            "alignment_format": row["alignment_format"],
            "first_16_bytes_hex": row["payload_first_16_bytes_hex"],
            "expected_magic_present": (
                str(row["payload_first_16_bytes_hex"]).startswith("1f8b")
                if row["alignment_format"] == "BAM"
                else str(row["payload_first_16_bytes_hex"]).startswith("4352414d")
            ),
        }
        for row in start_rows
    ]
    report = {
        "generated_at": datetime.now(timezone.utc).isoformat(),
        "source_inventory": source.name,
        "chunk_bytes": CHUNK,
        "repository_format_samples": len(selected),
        "range_requests": len(results),
        "strict_http_206_successes": sum(bool(row["strict_success"]) for row in results),
        "http_200_range_ignored": sum(row["range_result"] == "HTTP_200_range_ignored" for row in results),
        "unique_payload_sha256_hashes": len({str(row["payload_sha256"]) for row in results if row["payload_sha256"]}),
        "start_file_signature_checks": signature_checks,
        "start_file_signatures_valid": sum(bool(row["expected_magic_present"]) for row in signature_checks),
        "failures": [row for row in results if not row["strict_success"]],
        "csv": output.name,
    }
    report_path = output.with_suffix(".json")
    report_path.write_text(json.dumps(report, indent=2), encoding="utf-8")
    print(json.dumps(report), flush=True)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
