#!/usr/bin/env python3
"""A local authentication fixture, not a forwarding proxy or service benchmark."""
import base64
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
import json
import subprocess
import threading


class ProxyFixture(BaseHTTPRequestHandler):
    def log_message(self, *args):
        pass

    def do_GET(self):
        accepted = self.headers.get('Proxy-Authorization') == 'Basic ' + base64.b64encode(b'demo:correct').decode()
        body = b'Local authentication fixture only\n' if accepted else b'Authentication required\n'
        self.send_response(200 if accepted else 407)
        if not accepted:
            self.send_header('Proxy-Authenticate', 'Basic realm="local-lab"')
        self.send_header('Content-Length', str(len(body)))
        self.end_headers()
        self.wfile.write(body)

    def do_CONNECT(self):
        # Deliberately reject: no TCP tunnel or external connection is created.
        self.send_response(407)
        self.send_header('Proxy-Authenticate', 'Basic realm="local-lab"')
        self.send_header('Content-Length', '0')
        self.end_headers()


def main():
    server = ThreadingHTTPServer(('127.0.0.1', 0), ProxyFixture)
    thread = threading.Thread(target=server.serve_forever, daemon=True)
    thread.start()
    results = []
    try:
        for name, auth, url, expected in [
            ('missing credentials', [], 'http://example.invalid/check', ('407', '000')),
            ('wrong credentials', ['--proxy-user', 'demo:wrong'], 'http://example.invalid/check', ('407', '000')),
            ('accepted credentials', ['--proxy-user', 'demo:correct'], 'http://example.invalid/check', ('200', '000')),
            ('rejected CONNECT', [], 'https://example.invalid/check', ('000', '407')),
        ]:
            args = ['curl', '--silent', '--show-error', '--noproxy', '', '--connect-timeout', '2', '--max-time', '4',
                    '--proxy', 'http://127.0.0.1:' + str(server.server_port), *auth,
                    '--output', '/dev/null', '--write-out', '%{http_code} %{http_connect}', url]
            run = subprocess.run(args, capture_output=True, text=True, timeout=6)
            observed = tuple(run.stdout.split())
            if observed != expected:
                raise RuntimeError(name + ': unexpected protocol result ' + repr(observed))
            results.append({'case': name, 'target_http': observed[0], 'proxy_connect': observed[1], 'curl_exit': run.returncode})
    finally:
        server.shutdown()
        server.server_close()
        thread.join(timeout=2)
    print(json.dumps({'scope': 'loopback fixture; no external target or IPHTML proxy used', 'results': results}, indent=2))


if __name__ == '__main__':
    main()
