#!/usr/bin/env python3
"""Tiny HTTP model-service simulator for learning client/server boundaries."""
from __future__ import annotations
import argparse
import json
import threading
import urllib.request
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer

HOST = "127.0.0.1"
PORT = 18080


class Handler(BaseHTTPRequestHandler):
    server_version = "GNU-Learning-ModelService/1"

    def log_message(self, fmt, *args):
        return

    def do_GET(self):
        if self.path == "/health":
            self._json(200, {"status": "ok", "model": "learning-model"})
        else:
            self._json(404, {"error": "not_found"})

    def do_POST(self):
        if self.path != "/api/generate":
            self._json(404, {"error": "not_found"})
            return
        try:
            length = int(self.headers.get("Content-Length", "0"))
            body = json.loads(self.rfile.read(length) or b"{}")
        except (ValueError, json.JSONDecodeError):
            self._json(400, {"error": "invalid_json"})
            return
        if body.get("model") != "learning-model":
            self._json(404, {"error": "model_not_found", "expected": "learning-model"})
            return
        prompt = str(body.get("prompt", "")).strip()
        if not prompt:
            self._json(400, {"error": "prompt_required"})
            return
        self._json(200, {"model": "learning-model", "response": f"teaching-response:{prompt}", "done": True})

    def _json(self, status, payload):
        data = json.dumps(payload).encode()
        self.send_response(status)
        self.send_header("Content-Type", "application/json")
        self.send_header("Content-Length", str(len(data)))
        self.end_headers()
        self.wfile.write(data)


def start_server(port: int):
    server = ThreadingHTTPServer((HOST, port), Handler)
    thread = threading.Thread(target=server.serve_forever, daemon=True)
    thread.start()
    return server, thread


def post(url: str, payload: dict):
    request = urllib.request.Request(url, data=json.dumps(payload).encode(), headers={"Content-Type": "application/json"}, method="POST")
    with urllib.request.urlopen(request, timeout=3) as response:
        return response.status, json.loads(response.read())


def self_test() -> int:
    server, thread = start_server(0)
    port = server.server_address[1]
    try:
        status, payload = post(f"http://{HOST}:{port}/api/generate", {"model": "learning-model", "prompt": "hello"})
        assert status == 200
        assert payload["done"] is True
        assert payload["response"] == "teaching-response:hello"
        print(f"PASS client_to_service_http status={status}")
        print("PASS service_to_model_selection model=learning-model")
        print("PASS structured_json_response")
    finally:
        server.shutdown(); server.server_close(); thread.join(timeout=2)
    print("PASS stopped_service_would_fail_before_model_logic")
    return 0


def serve() -> int:
    server = ThreadingHTTPServer((HOST, PORT), Handler)
    print(f"Teaching model service listening on http://{HOST}:{PORT}")
    print("POST /api/generate with model=learning-model. Ctrl-C to stop.")
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        print("\nStopping cleanly.")
    finally:
        server.server_close()
    return 0


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument("--self-test", action="store_true")
    group.add_argument("--serve", action="store_true")
    args = parser.parse_args()
    raise SystemExit(self_test() if args.self_test else serve())
