"""Windows essentials and the native Winsock control.

Actual production UTF-8 env and Unicode RPC are exercised in
`test_code_execution_modes.py`; never reproduce the production scrubber here.
"""

import os
import subprocess
import sys
import textwrap
import time

import pytest

from tools.code_execution_env import _scrub_child_env
from tools import code_execution_env


def _no_passthrough(_):
    return False


@pytest.mark.parametrize("windows", [False, True])
@pytest.mark.parametrize("passthrough", [False, True])
def test_native_essentials_and_passthrough_priority(windows, passthrough):
    # Platform is explicit input to this pure policy helper, not a fake host.
    essentials = {
        "SYSTEMROOT": r"C:\Windows", "SystemRoot": r"C:\Windows",
        "SystemDrive": "C:", "WINDIR": r"C:\Windows",
        "ComSpec": r"C:\Windows\System32\cmd.exe", "comspec": r"C:\Windows\System32\cmd.exe",
        "APPDATA": r"C:\Users\alice\AppData\Roaming",
        "LOCALAPPDATA": r"C:\Users\alice\AppData\Local",
    }
    safe = {"PATH": r"C:\Windows\System32;C:\Python", "HOME": r"C:\Users\alice",
            "PATHEXT": ".COM;.EXE;.BAT;.CMD;.PY",
            "USERPROFILE": r"C:\Users\alice", "TEMP": r"C:\Users\alice\Temp"}
    secret = {"OPENAI_API_KEY": "fake-provider", "GITHUB_TOKEN": "fake-github",
              "MY_PASSWORD": "fake-password", "TENOR_API_KEY": "fake-third-party",
              "RANDOM_UNKNOWN_VAR": "unknown"}
    result = _scrub_child_env({**essentials, **safe, **secret}, is_windows=windows,
                             is_passthrough=lambda k: passthrough and k == "TENOR_API_KEY")
    assert result == {**safe, **(essentials if windows else {}),
                      **({"TENOR_API_KEY": "fake-third-party"} if passthrough else {})}


# ``platforms("windows")`` rather than ``skipif(sys.platform != "win32")``: the
# dedicated Windows CI job selects its files by grepping for the marker, so a
# bare skipif is invisible to it — the file is never imported there and these
# tests run on no host at all.
@pytest.mark.platforms("windows")
class TestWindowsSocketSmokeTest:
    """Integration-ish smoke test: spawn a child Python with a scrubbed
    env and confirm it can create an AF_INET socket.  This is the
    regression that motivated the fix — without SYSTEMROOT the child
    hits WinError 10106 before any RPC is attempted."""

    def test_child_can_create_socket_with_scrubbed_env(self):
        scrubbed = _scrub_child_env(os.environ, is_passthrough=_no_passthrough)

        # Build a tiny child script that simply opens an AF_INET socket.
        script = textwrap.dedent("""
            import socket, sys
            try:
                s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                s.close()
                print("OK")
                sys.exit(0)
            except OSError as exc:
                print(f"FAIL: {exc}")
                sys.exit(1)
        """).strip()

        result = subprocess.run(
            [sys.executable, "-c", script],
            env=scrubbed,
            capture_output=True,
            text=True,
            timeout=15,
        )
        assert result.returncode == 0, (
            f"Child failed to create socket with scrubbed env:\n"
            f"  stdout={result.stdout!r}\n"
            f"  stderr={result.stderr!r}\n"
            f"  scrubbed keys={sorted(scrubbed.keys())}"
        )
        assert "OK" in result.stdout


def _configured_timezone_child_env():
    return code_execution_env._build_child_env(
        rpc_endpoint="socket",
        rpc_token="token",
        tmpdir="/tmp/hermes-code-execution-test",
        child_python=sys.executable,
    )




@pytest.mark.platforms("windows")
def test_windows_live_child_offset_matches_os_zone_when_timezone_is_configured(monkeypatch):
    """The user-visible contract of #112233: with ``timezone:`` configured, a real Windows child
    must report the OS zone's UTC offset — an IANA name in ``TZ`` made the MSVC runtime derive
    ``time.timezone == 0`` (+01:00 instead of -07:00) while ``time.tzname`` still read correctly."""
    import json

    monkeypatch.setattr("hermes_time.get_timezone_name", lambda: "America/Los_Angeles")
    child_env = _configured_timezone_child_env()
    assert "TZ" not in child_env

    # The runner starts Python with TZ=UTC; its cached timezone is not the OS zone.
    # Query a fresh control process with TZ removed, independently of the builder.
    control_env = os.environ.copy()
    control_env.pop("TZ", None)
    timestamp = str(time.time())  # Both children observe the same instant across DST changes.
    script = (
        "import datetime, json, sys, time; "
        "instant = datetime.datetime.fromtimestamp(float(sys.argv[1]), datetime.timezone.utc); "
        "print(json.dumps([time.timezone, instant.astimezone().utcoffset().total_seconds()]))"
    )

    def read_timezone(env):
        result = subprocess.run(
            [sys.executable, "-c", script, timestamp],
            env=env, stdin=subprocess.DEVNULL, capture_output=True,
            text=True, encoding="utf-8", errors="replace", timeout=30,
        )
        assert result.returncode == 0, result.stderr
        return json.loads(result.stdout)

    assert read_timezone(child_env) == read_timezone(control_env)
