"""Shared, read-only ONTAP REST helper for the example scripts."""
import csv
import ipaddress
import re
from urllib.parse import urljoin, urlparse

import requests


def inventory(path):
    with open(path, newline="", encoding="utf-8-sig") as handle:
        reader = csv.DictReader(handle)
        if not reader.fieldnames or not {"Cluster", "Address"} <= set(reader.fieldnames):
            raise ValueError("Inventory needs Cluster,Address headers")
        rows = list(reader)
    if not rows:
        raise ValueError("Inventory contains no clusters")
    for row in rows:
        if not re.fullmatch(r"[A-Za-z0-9_-]+", row["Cluster"] or ""):
            raise ValueError("Invalid cluster name")
        try:
            ipaddress.ip_address(row["Address"])
        except ValueError as exc:
            raise ValueError(f"Use an IP address for {row['Cluster']}") from exc
    return rows


def records(session, address, endpoint, timeout=20):
    # Inventory accepts IP literals; the URL host is never taken from an API response.
    host = f"[{address}]" if ":" in address else address
    base = f"https://{host}"
    url = urljoin(base, endpoint)
    while url:
        parsed = urlparse(url)
        if parsed.scheme != "https" or parsed.netloc != urlparse(base).netloc or not parsed.path.startswith("/api/"):
            raise ValueError(f"Unexpected ONTAP pagination URL: {url}")
        response = session.get(url, timeout=timeout)
        response.raise_for_status()
        data = response.json()
        yield from data.get("records", [])
        next_href = data.get("_links", {}).get("next", {}).get("href")
        url = urljoin(base, next_href) if next_href else None
