#!/usr/bin/env python3
import html
import os
import sys
from collections import defaultdict
from typing import Any, Dict, List, Set
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
# check for the venv
from tools.lib import sanity_check
sanity_check.check_venv(__file__)
import orjson
Call = Dict[str, Any]
def clean_up_pattern(s: str) -> str:
    paren_level = 0
    in_braces = False
    result = ""
    prior_char = None
    for c in s:
        if c == "(":
            paren_level += 1
        if c == "<" and prior_char == "P":
            in_braces = True
        if in_braces or (paren_level == 0):
            if c != "?":
                result += c
        if c == ")":
            paren_level -= 1
        if c == ">":
            in_braces = False
        prior_char = c
    return result
def fix_test_name(s: str) -> str:
    return s.replace("zerver.tests.", "")
def create_single_page(pattern: str, out_dir: str, href: str, calls: List[Call]) -> None:
    fn = out_dir + "/" + href
    with open(fn, "w") as f:
        f.write(
            """
            
            """
        )
        f.write(f"
{html.escape(pattern)}
\n")
        calls.sort(key=lambda call: call["status_code"])
        for call in calls:
            f.write("
")
            f.write("\n{}".format(fix_test_name(call["test_name"])))
            f.write('')
            f.write(call["url"])
            f.write("
\n")
            f.write(call["method"] + "
\n")
            f.write("status code: {}
\n".format(call["status_code"]))
            f.write("
")
            f.write("
")
def create_user_docs() -> None:
    fn = "var/url_coverage.txt"  # TODO: make path more robust, maybe use json suffix
    out_dir = "var/api_docs"
    try:
        os.mkdir(out_dir)
    except OSError:
        pass
    main_page = out_dir + "/index.html"
    with open(main_page, "w") as f:
        f.write(
            """
            
            """
        )
        with open(fn, "rb") as coverage:
            calls = [orjson.loads(line) for line in coverage]
        pattern_dict: Dict[str, List[Call]] = defaultdict(list)
        for call in calls:
            if "pattern" in call:
                pattern = clean_up_pattern(call["pattern"])
                if pattern:
                    pattern_dict[pattern].append(call)
        patterns = set(pattern_dict.keys())
        tups = [
            ("api/v1/external", "webhooks"),
            ("api/v1", "api"),
            ("json", "legacy"),
        ]
        groups: Dict[str, Set[str]] = {}
        for prefix, name in tups:
            groups[name] = {p for p in patterns if p.startswith(prefix)}
            patterns -= groups[name]
        groups["other"] = patterns
        for name in ["api", "legacy", "webhooks", "other"]:
            f.write(name + " endpoints:\n\n")
            f.write("\n")
            for pattern in sorted(groups[name]):
                href = pattern.replace("/", "-") + ".html"
                link = f'{html.escape(pattern)}'
                f.write("- " + link + "
 \n")
                create_single_page(pattern, out_dir, href, pattern_dict[pattern])
            f.write("
")
            f.write("\n")
    print(f"open {main_page}")
if __name__ == "__main__":
    create_user_docs()