import json
from pathlib import Path
import subprocess
import tempfile
import unittest

import configure_vhost
import edge_health
from test_edge_inputs import configured


class Health(unittest.TestCase):
    def test_exact_edge_build_and_legacy_access_with_no_client_ingress_token(self):
        calls = []

        def fetch(url, *, headers=None):
            calls.append((url, headers))
            if url.startswith("https://edge.example") and (headers or {}).get(
                    edge_health.TOKEN_HEADER) != configured()["ingress_token"]:
                return 0, 403, b""
            return 0, 200, json.dumps({"build_sha": "a" * 40}).encode()

        with tempfile.TemporaryDirectory() as directory:
            root = Path(directory)
            config = root / ".backend-edge.json"
            config.write_text(json.dumps(configured()))
            (root / "backend-fixture.conf").write_text(configure_vhost.content("", "legacy.example", 32000))
            result = edge_health.verify(config, "fixture", "edge.example", "/healthz",
                                        nginx_dir=root, fetch=fetch)
        self.assertTrue(result["ok"])
        self.assertEqual(calls[-2:], [("https://legacy.example/healthz", None),
                                     ("https://app.pages.dev/api/healthz", None)])
        self.assertEqual(len(calls), 5)

    def test_redirect_partial_response_missing_build_and_mismatch_fail(self):
        cases = [(0, 302, b""), (28, 200, b'{"build_sha":"' + b"a" * 40 + b'"}'),
                 (0, 200, b"{}"), (0, 200, b'{"build_sha":"wrong"}'), (0, 200, b"invalid")]
        for response in cases:
            calls = []

            def fetch(url, **kwargs):
                calls.append(url)
                return response

            with self.subTest(response=response), self.assertRaises(ValueError):
                edge_health.healthy("https://app.pages.dev/api/healthz", "a" * 40,
                                    fetch=fetch, sleep=lambda _seconds: None)
            self.assertEqual(len(calls), 15)

    def test_origin_that_accepts_a_missing_token_fails_before_public_probe(self):
        with tempfile.TemporaryDirectory() as directory:
            config = Path(directory) / ".backend-edge.json"
            config.write_text(json.dumps(configured()))
            with self.assertRaisesRegex(ValueError, "ingress_unverified"):
                edge_health.verify(config, "fixture", "edge.example", "/healthz",
                                   fetch=lambda *args, **kwargs: (0, 200, b"{}"))

    def test_curl_keeps_token_out_of_argv_and_deletes_private_temporary_files(self):
        retained = []

        def run(command, **kwargs):
            self.assertNotIn(configured()["ingress_token"], str(command))
            config = Path(command[command.index("--config") + 1])
            retained.append(config.parent)
            self.assertEqual(config.stat().st_mode & 0o777, 0o600)
            self.assertIn(configured()["ingress_token"], config.read_text())
            for unsafe in ("--insecure", "-k", "--location", "-L"):
                self.assertNotIn(unsafe, command)
            Path(command[command.index("--output") + 1]).write_text('{"build_sha":"' + "a" * 40 + '"}')
            return subprocess.CompletedProcess(command, 0, stdout=b"200", stderr=b"")

        result = edge_health.request("https://edge.example/healthz",
                                     headers={edge_health.TOKEN_HEADER: configured()["ingress_token"]}, run=run)
        self.assertEqual(result[:2], (0, 200))
        self.assertFalse(retained[0].exists())
