#!/usr/bin/env python3
"""Serve a local, read-only pagination regression lab using Python 3.

Run: python3 order_filter_lab.py --mode broken --port 8765
Stop with Ctrl-C. Restart with --mode fixed to compare the same fixture.
"""

import argparse
from html import escape
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from urllib.parse import parse_qs, urlencode, urlsplit

ORDERS = (
    ("ORD-101", "Open"),
    ("ORD-102", "Open"),
    ("ORD-103", "Closed"),
    ("ORD-104", "Closed"),
    ("ORD-105", "Open"),
    ("ORD-106", "Open"),
)
FILTERS = ("All orders", "Open", "Closed", "Cancelled")
PAGE_SIZE = 2


def page_url(status, page):
    query = {}
    if status != "All orders":
        query["status"] = status.lower()
    query["page"] = page
    return "/orders?" + urlencode(query)


def link(href, label, current=False):
    marker = ' aria-current="page"' if current else ""
    return f'<a href="{escape(href, quote=True)}"{marker}>{escape(label)}</a>'


def render(mode, status, page):
    selected = [row for row in ORDERS if status == "All orders" or row[1] == status]
    pages = max(1, (len(selected) + PAGE_SIZE - 1) // PAGE_SIZE)
    if page < 1 or page > pages:
        return None
    start = (page - 1) * PAGE_SIZE
    visible = selected[start:start + PAGE_SIZE]
    filters = " | ".join(link(page_url(f, 1), f, current=f == status) for f in FILTERS)
    if visible:
        rows = "".join(
            f"<tr><td>{escape(order_id)}</td><td>{escape(state)}</td></tr>"
            for order_id, state in visible
        )
        content = (
            '<table><caption>Matching orders</caption><thead><tr>'
            '<th scope="col">Order</th><th scope="col">Status</th></tr></thead>'
            f"<tbody>{rows}</tbody></table>"
        )
    else:
        content = '<p role="status">No matching orders.</p>'
    pagination = []
    if page > 1:
        pagination.append(link(page_url(status, page - 1), "Previous page"))
    if page < pages:
        # The sole deliberate fault drops the active filter from the next link.
        next_status = "All orders" if mode == "broken" else status
        pagination.append(link(page_url(next_status, page + 1), "Next page"))
    return f"""<!doctype html><html lang="en"><meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Order filter lab</title>
<style>body{{font:1.05rem/1.6 system-ui;max-width:45rem;margin:2rem auto;padding:0 1rem}}
th,td{{padding:.35rem 1rem;text-align:left}}caption{{text-align:left}}
nav a{{display:inline-block;padding:.3rem}}[aria-current="page"]{{font-weight:bold}}</style>
<main><h1>Orders</h1><nav aria-label="Order status">{filters}</nav>
<p>Filter: <strong>{escape(status)}</strong>. Page {page} of {pages}.</p>
{content}<nav aria-label="Pagination">{' | '.join(pagination)}</nav></main></html>"""


class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        uri = urlsplit(self.path)
        if uri.path not in ("/", "/orders"):
            self.send_error(404)
            return
        query = parse_qs(uri.query)
        status_arg = query.get("status", ["all orders"])[0]
        status = next((f for f in FILTERS if f.lower() == status_arg), None)
        try:
            page = int(query.get("page", [1])[0])
            html = render(self.server.mode, status, page) if status else None
        except ValueError:
            html = None
        if html is None:
            self.send_error(400, "Unknown filter or page")
            return
        payload = html.encode("utf-8")
        self.send_response(200)
        self.send_header("Content-Type", "text/html; charset=utf-8")
        self.send_header("Cache-Control", "no-store")
        self.send_header("Content-Length", str(len(payload)))
        self.end_headers()
        self.wfile.write(payload)


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--mode", choices=("broken", "fixed"), default="broken")
    parser.add_argument("--port", type=int, default=8765)
    args = parser.parse_args()
    with ThreadingHTTPServer(("127.0.0.1", args.port), Handler) as server:
        server.mode = args.mode
        print(f"{args.mode}: http://127.0.0.1:{server.server_port}/orders", flush=True)
        try:
            server.serve_forever()
        except KeyboardInterrupt:
            pass


if __name__ == "__main__":
    main()
