"""Integration: route-owned `pipelock.tls_passthrough` renders into
pipelock's `tls_interception.passthrough_domains`, so request bodies
that would otherwise trip the body-scan layer are not inspected and the
request reaches the provider TLS endpoint.

Probe: POST the canonical zero-entropy 12-word BIP-39 mnemonic
(`abandon` × 11 + `about`) — checksum-valid by construction — to
`https://api.anthropic.com/v1/messages`. With the route policy,
pipelock relays the CONNECT opaquely and the upstream replies with
whatever it likes (401/4xx from Anthropic for an unauthenticated junk
POST). We assert that the verdict is NOT pipelock's block.
"""

from __future__ import annotations

import os
import shutil
import tempfile
import unittest
from pathlib import Path

from bot_bottle.backend import BottleSpec, get_bottle_backend
from bot_bottle.manifest import Manifest
from tests._docker import skip_unless_docker


# Canonical BIP-39 12-word test mnemonic. Valid SHA-256 checksum —
# pipelock's seed-phrase scanner (default `verify_checksum: true`)
# fires on this exact string if it ever sees the cleartext body.
_BIP39_PHRASE = (
    "abandon abandon abandon abandon abandon abandon "
    "abandon abandon abandon abandon abandon about"
)


@skip_unless_docker()
class TestPipelockLlmPassthrough(unittest.TestCase):
    @unittest.skipIf(
        os.environ.get("GITEA_ACTIONS") == "true",
        "skipped under act_runner: docker socket mount topology breaks "
        "in-process visibility of networks created on the host daemon",
    )
    def test_bip39_body_to_anthropic_is_not_blocked(self):
        manifest = Manifest.from_json_obj({
            "bottles": {
                "dev": {
                    "env": {"SEED": _BIP39_PHRASE},
                    "egress": {"routes": [{
                        "host": "api.anthropic.com",
                        "pipelock": {"tls_passthrough": True},
                    }]},
                },
            },
            "agents": {
                "demo": {"skills": [], "prompt": "", "bottle": "dev"},
            },
        })
        backend = get_bottle_backend()
        stage_dir = Path(tempfile.mkdtemp(prefix="cb-test-stage."))
        try:
            spec = BottleSpec(
                manifest=manifest,
                agent_name="demo",
                copy_cwd=False,
                user_cwd=str(stage_dir),
            )
            plan = backend.prepare(spec, stage_dir=stage_dir)
            with backend.launch(plan) as bottle:
                script = (
                    "set -eu\n"
                    'curl --proxy "$HTTPS_PROXY" -s --max-time 10 \\\n'
                    "  -w 'status=%{http_code}\\n' \\\n"
                    "  -o /tmp/probe-body.txt \\\n"
                    '  -X POST -H "content-type: application/json" \\\n'
                    '  --data "{\\"phrase\\": \\"$SEED\\"}" \\\n'
                    "  https://api.anthropic.com/v1/messages\n"
                    'echo "body=$(head -c 200 /tmp/probe-body.txt)"\n'
                )
                result = bottle.exec(script)
        finally:
            shutil.rmtree(stage_dir, ignore_errors=True)

        self.assertEqual(
            0, result.returncode,
            f"exec wrapper failed: stdout={result.stdout!r} "
            f"stderr={result.stderr!r}",
        )
        # The pipelock block verdict starts with `blocked: ` in the
        # body. Anything else (auth error, 401, 4xx from Anthropic) is
        # an acceptable outcome — it means the body was NOT inspected
        # by the proxy and the request was relayed to the upstream
        # TLS endpoint.
        self.assertNotIn(
            "body=blocked: ", result.stdout,
            f"unexpected pipelock body-scan block on api.anthropic.com; "
            f"expected passthrough to skip MITM. got: {result.stdout!r}",
        )
        self.assertNotIn(
            "BIP-39", result.stdout,
            f"BIP-39 verdict should never appear for api.anthropic.com "
            f"requests under tls_interception.passthrough_domains; "
            f"got: {result.stdout!r}",
        )


if __name__ == "__main__":
    unittest.main()
