"""Fetch authorised report metadata using Python 3's standard library."""
import json
import os
import urllib.error
import urllib.parse
import urllib.request

ORIGIN = "https://secure.ethicsportal.eu"


class NoRedirects(urllib.request.HTTPRedirectHandler):
    def redirect_request(self, req, fp, code, msg, headers, newurl):
        return None


def reports(token, organization_id, opener=None):
    base = f"{ORIGIN}/organizations/{urllib.parse.quote(organization_id, safe='')}/whistleblower/reports.json"
    opener = opener or urllib.request.build_opener(NoRedirects())
    cursor, seen = None, set()
    while True:
        query = {"limit": "100", **({"cursor": cursor} if cursor else {})}
        request = urllib.request.Request(f"{base}?{urllib.parse.urlencode(query)}", headers={
            "Authorization": f"Bearer {token}", "Accept": "application/json"
        })
        with opener.open(request, timeout=20) as response:
            page = json.load(response)
        if not isinstance(page, dict) or not isinstance(page.get("data"), list):
            raise ValueError("Expected a report list")
        yield from page["data"]
        cursor = page.get("next_cursor")
        if not cursor:
            return
        if cursor in seen:
            raise ValueError("Repeated pagination cursor; restart reconciliation")
        seen.add(cursor)


if __name__ == "__main__":
    try:
        for report in reports(os.environ["ETHICSPORTAL_TOKEN"], os.environ["ETHICSPORTAL_ORGANIZATION_ID"]):
            print(json.dumps(report))
    except urllib.error.HTTPError as error:
        retry = error.headers.get("Retry-After", "unspecified") if error.code == 429 else None
        raise SystemExit(f"API returned HTTP {error.code}" + (f"; retry after {retry} seconds" if retry else "")) from None
