"""Extract request-level failures from an Apifox HTML export without executing it."""
import json
import re
import sys
from html.parser import HTMLParser
from pathlib import Path
from urllib.parse import urlsplit


class Report(HTMLParser):
    def __init__(self):
        super().__init__()
        self.depth = 0
        self.current = None
        self.cards = {}
        self.failed_ids = set()

    def handle_starttag(self, tag, attrs):
        attrs = dict(attrs)
        if tag == "div":
            self.depth += 1
            if attrs.get("id", "").startswith("request-"):
                self.current = (attrs["id"], self.depth, [])
        if tag == "a" and attrs.get("data-click") == "to-card":
            self.failed_ids.add(attrs.get("href", "").lstrip("#"))

    def handle_endtag(self, tag):
        if tag == "div":
            if self.current and self.current[1] == self.depth:
                self.cards[self.current[0]] = self.current[2]
                self.current = None
            self.depth -= 1

    def handle_data(self, value):
        if self.current and value.strip():
            self.current[2].append(value.strip())


def extract(path):
    report = Report()
    report.feed(Path(path).read_text())
    rows = []
    for key, text in report.cards.items():
        if key not in report.failed_ids:
            continue
        def field(name):
            return text[text.index(name) + 1] if name in text else None
        url = urlsplit(field("URL") or "")
        assertions = [text[i - 1] for i, value in enumerate(text) if value == "失败" and i]
        rows.append({
            "request_id": key, "name": text[0], "method": field("Method"),
            "port": url.port, "path": url.path, "http": field("HTTP 状态码"),
            "failed_assertions": int(field("断言失败数") or 0),
            "assertions": assertions,
            "schema_only_failure": not assertions,
        })
    return rows


if __name__ == "__main__":
    print(json.dumps(extract(sys.argv[1]), ensure_ascii=False, indent=2))
