#!/usr/bin/env python3
"""
Fake cloud-metadata stub for Tech Forge curl labs.
Binds ONLY to 127.0.0.1 so it is never reachable from other hosts.
Mimics common *path shapes* (AWS / GCP style) with JSON stubs — not real IMDS.

Usage:
  python3 fake-metadata.py
  # then:
  curl -s http://127.0.0.1:9090/latest/meta-data/
  curl -s -H 'Metadata-Flavor: Google' http://127.0.0.1:9090/computeMetadata/v1/instance/id
"""
from __future__ import annotations

import json
from http.server import BaseHTTPRequestHandler, HTTPServer

HOST = "127.0.0.1"
PORT = 9090

# Path → (status, body, content-type)
STUBS: dict[str, tuple[int, str, str]] = {
    "/": (
        200,
        "fake-metadata stub — Tech Forge lab helper\n"
        "Try /latest/meta-data/ or /computeMetadata/v1/\n",
        "text/plain",
    ),
    "/latest/meta-data/": (
        200,
        "ami-id\nhostname\ninstance-id\nlocal-ipv4\n",
        "text/plain",
    ),
    "/latest/meta-data/ami-id": (200, "ami-0fakecehlab0001\n", "text/plain"),
    "/latest/meta-data/hostname": (200, "fake-imds.local\n", "text/plain"),
    "/latest/meta-data/instance-id": (200, "i-0faketfcurl01\n", "text/plain"),
    "/latest/meta-data/local-ipv4": (200, "127.0.0.1\n", "text/plain"),
    "/latest/meta-data/iam/security-credentials/": (
        200,
        "FakeLabRole\n",
        "text/plain",
    ),
    "/latest/meta-data/iam/security-credentials/FakeLabRole": (
        200,
        json.dumps(
            {
                "Code": "Success",
                "Type": "AWS-HMAC",
                "AccessKeyId": "ASIAFAKELABONLY",
                "SecretAccessKey": "fake/secret/for/lab/only",
                "Token": "fake-session-token-lab-only",
                "Expiration": "2099-01-01T00:00:00Z",
            },
            indent=2,
        )
        + "\n",
        "application/json",
    ),
    "/computeMetadata/v1/": (
        200,
        "instance/\nproject/\n",
        "text/plain",
    ),
    "/computeMetadata/v1/instance/id": (200, "4242424242424242424\n", "text/plain"),
    "/computeMetadata/v1/instance/hostname": (
        200,
        "fake-gce.lab.internal\n",
        "text/plain",
    ),
    "/computeMetadata/v1/instance/service-accounts/default/email": (
        200,
        "fake-sa@techforge-lab.iam.gserviceaccount.com\n",
        "text/plain",
    ),
}


class Handler(BaseHTTPRequestHandler):
    server_version = "FakeMetadata/1.0"

    def do_GET(self) -> None:  # noqa: N802
        path = self.path.split("?", 1)[0]
        # GCP-style clients often send Metadata-Flavor: Google
        flavor = self.headers.get("Metadata-Flavor", "")
        meta_true = self.headers.get("Metadata", "")

        if path.startswith("/computeMetadata/") and flavor != "Google":
            self._send(
                403,
                "Missing or wrong Metadata-Flavor header (expected: Google)\n",
                "text/plain",
            )
            return

        # Optional: AWS IMDS v2 header is not required here; we stay open for teaching -H flags.
        _ = meta_true  # acknowledged for students practicing -H 'Metadata: true'

        if path in STUBS:
            status, body, ctype = STUBS[path]
            self._send(status, body, ctype)
            return

        self._send(404, f"Unknown path: {path}\n", "text/plain")

    def log_message(self, fmt: str, *args) -> None:
        print(f"[fake-metadata] {self.address_string()} - {fmt % args}")

    def _send(self, status: int, body: str, ctype: str) -> None:
        data = body.encode()
        self.send_response(status)
        self.send_header("Content-Type", ctype)
        self.send_header("Content-Length", str(len(data)))
        self.send_header("X-Lab-Helper", "techforge-fake-metadata")
        self.end_headers()
        self.wfile.write(data)


def main() -> None:
    # Refuse anything other than loopback bind.
    if HOST not in ("127.0.0.1", "localhost", "::1"):
        raise SystemExit("Refusing to bind outside loopback.")
    httpd = HTTPServer((HOST, PORT), Handler)
    print(f"Fake metadata listening on http://{HOST}:{PORT}/ (Ctrl+C to stop)")
    print("Examples:")
    print(f"  curl -s http://{HOST}:{PORT}/latest/meta-data/")
    print(
        f"  curl -s -H 'Metadata-Flavor: Google' "
        f"http://{HOST}:{PORT}/computeMetadata/v1/instance/id"
    )
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        print("\nStopped.")


if __name__ == "__main__":
    main()
