"""LockedIn Labs: a deliberately local, synthetic container lifecycle exercise.

Python 3.11+; standard library only. Run --check before building the image.
This teaching server has no user authentication. Bind its published port to
127.0.0.1, use only the supplied fictional record, and never deploy it publicly.
"""
import argparse
from contextlib import closing
import json
import os
from pathlib import Path
import sqlite3
import tempfile
from http.server import BaseHTTPRequestHandler, HTTPServer
from uuid import uuid4


REVIEW = {"id": "R-104", "status": "pending"}


class ReviewStore:
    def __init__(self, folder):
        Path(folder).mkdir(parents=True, exist_ok=True)
        self.path = Path(folder) / "review.sqlite3"
        with closing(sqlite3.connect(self.path)) as connection, connection:
            connection.execute("CREATE TABLE IF NOT EXISTS review (id TEXT PRIMARY KEY, status TEXT NOT NULL)")

    def read(self):
        with closing(sqlite3.connect(self.path)) as connection:
            row = connection.execute("SELECT id, status FROM review WHERE id = ?", (REVIEW["id"],)).fetchone()
        return {"id": row[0], "status": row[1]} if row else None

    def save(self, record):
        if record != REVIEW:
            raise ValueError("Use only the supplied fictional R-104 pending record.")
        with closing(sqlite3.connect(self.path)) as connection, connection:
            connection.execute("INSERT OR REPLACE INTO review (id, status) VALUES (?, ?)", (record["id"], record["status"]))
        return self.read()


def handler_for(store, instance):
    class Handler(BaseHTTPRequestHandler):
        def setup(self):
            super().setup()
            self.connection.settimeout(5)

        def reply(self, status, value):
            body = json.dumps(value).encode()
            self.send_response(status)
            self.send_header("Content-Type", "application/json")
            self.send_header("Content-Length", str(len(body)))
            self.send_header("Cache-Control", "no-store")
            self.end_headers()
            self.wfile.write(body)

        def do_GET(self):
            if self.path == "/healthz":
                self.reply(200, {"process": "responding", "instance": instance})
            elif self.path == "/review":
                self.reply(200, {"instance": instance, "review": store.read()})
            else:
                self.reply(404, {"error": "Use /healthz or /review."})

        def do_POST(self):
            if self.path != "/review":
                self.reply(404, {"error": "Use /review."})
                return
            try:
                length = int(self.headers.get("Content-Length", "0"))
                if self.headers.get("Content-Type") != "application/json" or not 0 < length <= 256:
                    raise ValueError("Send the supplied small JSON record.")
                record = json.loads(self.rfile.read(length))
                self.reply(200, {"instance": instance, "review": store.save(record)})
            except (ValueError, UnicodeError):
                self.reply(400, {"error": "Send only the supplied R-104 pending JSON record."})

        def log_message(self, format, *args):
            # Record no request headers or bodies.
            pass

    return Handler


def check():
    with tempfile.TemporaryDirectory(prefix="lockedin-container-check-") as folder:
        store = ReviewStore(folder)
        assert store.read() is None
        assert store.save(REVIEW) == REVIEW
        assert ReviewStore(folder).read() == REVIEW, "A new process can read the same database."
        try:
            store.save({"id": "R-104", "status": "approved"})
        except ValueError:
            pass
        else:
            raise AssertionError("The teaching server must refuse other records.")
        assert ReviewStore(folder).read() == REVIEW
        with tempfile.TemporaryDirectory(prefix="lockedin-container-empty-") as empty:
            assert ReviewStore(empty).read() is None, "A different empty path does not inherit the record."
    print("PASS: empty state, write, reopen, invalid-record refusal and a separate empty path.")
    print("These are application checks. Run the Docker walkthrough to observe actual container and volume lifecycles.")


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--check", action="store_true")
    args = parser.parse_args()
    if args.check:
        check()
        return
    store = ReviewStore(os.environ.get("LAB_DATA_DIR", "./container-lab-data"))
    instance = uuid4().hex[:12]
    host = os.environ.get("LAB_BIND", "127.0.0.1")
    server = HTTPServer((host, 8080), handler_for(store, instance))
    print(json.dumps({"process": "started", "instance": instance, "listen": f"{host}:8080"}), flush=True)
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        pass
    finally:
        server.server_close()


if __name__ == "__main__":
    main()
