"""Measure requested and effective read policy, without assuming kwargs took effect."""
import argparse
import json
from pathlib import Path
import tempfile
import zarr
from experiment import VALUES, FILL, build, require

ROUTES = ("open_array-config", "open-config", "with_config", "global-config")


def observe(array):
    result = {"effective_read_missing_chunks": array.config.read_missing_chunks}
    try:
        result.update(status="ok", values=array[:].tolist())
    except Exception as error:
        result.update(status="error", error_type=type(error).__name__)
    return result


def run():
    rows = []
    with tempfile.TemporaryDirectory(prefix="hesela-zarr-routing-") as temp:
        for layout in ("plain", "shard-end"):
            root = Path(temp) / layout
            build(root, layout, "sparse-tail")
            for route in ROUTES:
                if route == "open_array-config":
                    a = zarr.open_array(str(root), mode="r", config={"read_missing_chunks": False})
                elif route == "open-config":
                    a = zarr.open(str(root), mode="r", config={"read_missing_chunks": False})
                elif route == "with_config":
                    a = zarr.open_array(str(root), mode="r").with_config({"read_missing_chunks": False})
                else:
                    with zarr.config.set({"array.read_missing_chunks": False}):
                        a = zarr.open_array(str(root), mode="r")
                rows.append({"layout": layout, "route": route, "requested_read_missing_chunks": False,
                             "result": observe(a)})
    report = {"schema_version": 1, "zarr_version": zarr.__version__, "observations": rows,
              "interpretation": "open_array kwargs are documented as create kwargs; existing-array open does not forward config"}
    validate(report)
    return report


def validate(report):
    require(report["zarr_version"] == "3.4.1", "version scope")
    rows = report["observations"]
    keys = [(r["layout"], r["route"]) for r in rows]
    require(len(keys) == len(set(keys)) == 8, "missing/duplicate routes")
    require(set(keys) == {(l, r) for l in ("plain", "shard-end") for r in ROUTES}, "route inventory")
    for row in rows:
        require(row["requested_read_missing_chunks"] is False, "request changed")
        result = row["result"]
        effective = row["route"] == "open_array-config"
        require(result["effective_read_missing_chunks"] is effective, "effective policy changed")
        if row["layout"] == "plain" and not effective:
            require(result == {"effective_read_missing_chunks": False, "status": "error",
                               "error_type": "ChunkNotFoundError"}, "missing strict rejection")
        else:
            require(result == {"effective_read_missing_chunks": effective, "status": "ok",
                               "values": VALUES[:4] + [FILL] * 4}, "wrong values")


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--output", required=True, type=Path)
    args = parser.parse_args()
    args.output.write_text(json.dumps(run(), sort_keys=True, indent=2) + "\n")
    print("validated 8 requested/effective-policy controls")
