#!/usr/bin/env python3
"""Fake `webglass` executable for tests (tests/test_webglass_adapter.py).

Never the real binary: this script never touches a network or a browser. It
prints a canned WebOperationResult JSON payload to stdout so
substack_cli.substack.webglass can be exercised without depending on the real
webglass-cli tool being installed or reachable.

Canned response selection (checked in this order):
  1. ``WEBGLASS_FAKE_SEQUENCE_DIR`` — a directory holding ``response-0.json``,
     ``response-1.json``, ... one per expected invocation, for flows that make
     several webglass calls in a row (``post publish`` is subscription ->
     create draft -> publish). Each invocation is its own process, so the
     cursor lives on disk in ``<dir>/cursor``; once the sequence is exhausted
     the last response is reused. Every invocation's argv is appended as a
     JSON array to ``<dir>/calls.jsonl`` so a test can assert on the exact
     method, URL and body of each call in the flow.
  2. ``WEBGLASS_FAKE_RESPONSE_FILE`` — path to a JSON file to print verbatim.
  3. ``WEBGLASS_FAKE_RESPONSE`` — a JSON string to print verbatim.
  4. Fallback: a minimal "succeeded" WebOperationResult.

The fake also honors ``WEBGLASS_FAKE_EXIT`` (an integer exit code to return)
so tests can simulate a nonzero exit alongside the JSON body,
``WEBGLASS_FAKE_STDERR`` to also write a line to stderr, and
``WEBGLASS_FAKE_SLEEP`` (seconds, float) to stall *before* printing anything
so the adapter's subprocess timeout can be exercised. All three are optional
and default to "off", so every existing caller is unaffected.
"""

from __future__ import annotations

import json
import os
import sys
import time

DEFAULT_RESULT = {
    "schema_version": 1,
    "operation_id": "operation-fake",
    "kind": "fake.op",
    "lifecycle_state": "succeeded",
    "content": {"trusted": {}, "untrusted": {}, "sensitive": {}, "derived": {}},
    "error": None,
}


def sequenced_payload(directory: str) -> str:
    """Record this invocation and return the response canned for its turn."""
    with open(os.path.join(directory, "calls.jsonl"), "a", encoding="utf-8") as handle:
        handle.write(json.dumps(sys.argv[1:]) + "\n")

    cursor_path = os.path.join(directory, "cursor")
    try:
        with open(cursor_path, "r", encoding="utf-8") as handle:
            cursor = int(handle.read().strip() or "0")
    except FileNotFoundError:
        cursor = 0
    with open(cursor_path, "w", encoding="utf-8") as handle:
        handle.write(str(cursor + 1))

    while cursor >= 0:
        candidate = os.path.join(directory, "response-%d.json" % cursor)
        if os.path.exists(candidate):
            with open(candidate, "r", encoding="utf-8") as handle:
                return handle.read()
        cursor -= 1
    return json.dumps(DEFAULT_RESULT)


def _url_arg(argv: list[str]) -> str | None:
    for i, token in enumerate(argv):
        if token == "--url" and i + 1 < len(argv):
            return argv[i + 1]
        if token.startswith("--url="):
            return token[len("--url=") :]
    return None


def _response_by_url(argv: list[str]) -> str | None:
    """``WEBGLASS_FAKE_RESPONSE_BY_URL``: JSON object mapping a URL substring to a response."""
    raw_map = os.environ.get("WEBGLASS_FAKE_RESPONSE_BY_URL")
    if not raw_map:
        return None
    url = _url_arg(argv)
    if url is None:
        return None
    try:
        by_url = json.loads(raw_map)
    except json.JSONDecodeError:
        return None
    if not isinstance(by_url, dict):
        return None
    for key, value in by_url.items():
        if key in url:
            return value if isinstance(value, str) else json.dumps(value)
    return None


def main() -> int:
    stall = float(os.environ.get("WEBGLASS_FAKE_SLEEP", "0") or "0")
    if stall > 0:
        time.sleep(stall)

    sequence_dir = os.environ.get("WEBGLASS_FAKE_SEQUENCE_DIR")
    response_by_url = _response_by_url(sys.argv[1:])
    response_file = os.environ.get("WEBGLASS_FAKE_RESPONSE_FILE")
    response_text = os.environ.get("WEBGLASS_FAKE_RESPONSE")

    if sequence_dir:
        payload = sequenced_payload(sequence_dir)
    elif response_by_url is not None:
        payload = response_by_url
    elif response_file:
        with open(response_file, "r", encoding="utf-8") as handle:
            payload = handle.read()
    elif response_text:
        payload = response_text
    else:
        payload = json.dumps(DEFAULT_RESULT)

    sys.stdout.write(payload)
    if not payload.endswith("\n"):
        sys.stdout.write("\n")

    stderr_line = os.environ.get("WEBGLASS_FAKE_STDERR")
    if stderr_line:
        sys.stderr.write(stderr_line)
        if not stderr_line.endswith("\n"):
            sys.stderr.write("\n")

    return int(os.environ.get("WEBGLASS_FAKE_EXIT", "0"))


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