#!/usr/bin/env python3
import json
import os
import urllib.error
import urllib.request
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer


HOST = "0.0.0.0"
PORT = 9090
def read_flag() -> str:
    return os.environ.get("FLAG", "").strip()



def fetch_json(url: str, payload: dict | None = None) -> dict:
    data = None
    headers = {}
    if payload is not None:
        data = json.dumps(payload).encode("utf-8")
        headers["Content-Type"] = "application/json"
    req = urllib.request.Request(url, data=data, headers=headers)
    with urllib.request.urlopen(req, timeout=10) as response:
        return json.loads(response.read().decode("utf-8"))


def expect(name: str, actual: bool, wanted: bool) -> tuple[bool, str]:
    status = "PASS" if actual == wanted else "FAIL"
    return actual == wanted, f"{status}: {name} -> ожидалось {wanted}, получено {actual}"


def build_report() -> tuple[int, str]:
    try:
        rules = fetch_json("http://router:8081/iptables/forward")
    except urllib.error.URLError as exc:
        return 500, f"Чекер не смог обратиться к API роутера: {exc}\n"

    lines = ["Текущие правила FORWARD:", rules.get("forward", "")]
    checks = [
        expect("tcp/22 к серверу в DMZ", fetch_json("http://router:8081/probe/tcp", {"host": "192.168.30.10", "port": 22})["ok"], True),
        expect("tcp/8080 к серверу в DMZ", fetch_json("http://router:8081/probe/tcp", {"host": "192.168.30.10", "port": 8080})["ok"], False),
        expect("tcp/22 к другому хосту в DMZ", fetch_json("http://router:8081/probe/tcp", {"host": "192.168.30.20", "port": 22})["ok"], False),
        expect("icmp к серверу в DMZ", fetch_json("http://router:8081/probe/ping", {"host": "192.168.30.10"})["ok"], False),
    ]
    lines.extend(message for _, message in checks)
    if all(result for result, _ in checks):
        lines.append("OK: поведение firewall соответствует условию задания.")
        lines.append(f"Ответ задания: {read_flag()}")
        return 200, "\n".join(lines) + "\n"
    lines.append("FAIL: поведение firewall не соответствует условию задания.")
    return 400, "\n".join(lines) + "\n"


class Handler(BaseHTTPRequestHandler):
    def do_GET(self) -> None:
        if self.path == "/check":
            status, report = build_report()
            body = report.encode("utf-8")
            self.send_response(status)
            self.send_header("Content-Type", "text/plain; charset=utf-8")
            self.send_header("Content-Length", str(len(body)))
            self.end_headers()
            self.wfile.write(body)
            return
        if self.path == "/health":
            body = b"ok\n"
            self.send_response(200)
            self.send_header("Content-Type", "text/plain; charset=utf-8")
            self.send_header("Content-Length", str(len(body)))
            self.end_headers()
            self.wfile.write(body)
            return
        self.send_response(404)
        self.end_headers()

    def log_message(self, format: str, *args) -> None:
        return


if __name__ == "__main__":
    ThreadingHTTPServer((HOST, PORT), Handler).serve_forever()
