#!/usr/bin/env python3
"""Query bundled TSL API reference data."""
import argparse
import re
import sys
from pathlib import Path

ENTRY_RE = re.compile(r"^(#{2,3})(?!#)\s+`(.+?)`\s*$")
HEADING_RE = re.compile(r"^(#{1,6})(?!#)\s+")
SKILL_ROOT = Path(__file__).resolve().parents[1]
DEFAULT_TSV = SKILL_ROOT / "data" / "function_index.tsv"
DEFAULT_CODEGEN_ROOT = SKILL_ROOT / "references" / "codegen"


def find_tsv(start):
    """Walk upward from start and find a bundled or legacy function_index.tsv."""
    for directory in [start, *start.parents]:
        candidates = [
            directory / "data" / "function_index.tsv",
            directory / "function_index.tsv",
            directory / "docs" / "tsl" / "codegen" / "function_index.tsv",
        ]
        for candidate in candidates:
            if candidate.is_file():
                return candidate
    return None


def load_rows(tsv_path):
    lines = tsv_path.read_text(encoding="utf-8").splitlines()
    if not lines:
        return []
    header = lines[0].split("\t")
    rows = []
    for line in lines[1:]:
        if not line.strip():
            continue
        values = line.split("\t")
        values += [""] * (len(header) - len(values))
        rows.append(dict(zip(header, values)))
    return rows


def search_exact(rows, name):
    key = name.lower()
    return [row for row in rows if row.get("name", "").lower() == key]


def search_keyword(rows, terms):
    lowered_terms = [term.lower() for term in terms]
    matches = []
    for row in rows:
        haystack = " ".join(
            [
                row.get("name", ""),
                row.get("signature", ""),
                row.get("module", ""),
                row.get("summary", ""),
            ]
        ).lower()
        if all(term in haystack for term in lowered_terms):
            matches.append(row)
    return matches


def slice_entry(codegen_root, page, signature):
    md = codegen_root / page
    if not md.is_file():
        return ""
    lines = md.read_text(encoding="utf-8").splitlines()
    start = None
    for idx, line in enumerate(lines):
        match = ENTRY_RE.match(line)
        if match and match.group(2) == signature:
            start = idx
            start_level = len(match.group(1))
            break
    if start is None:
        return ""

    end = len(lines)
    for idx in range(start + 1, len(lines)):
        entry_match = ENTRY_RE.match(lines[idx])
        if entry_match:
            end = idx
            break
        heading_match = HEADING_RE.match(lines[idx])
        if heading_match and len(heading_match.group(1)) <= start_level:
            end = idx
            break
    block = lines[start:end]
    while block and not block[-1].strip():
        block.pop()
    return "\n".join(block)


def format_row(row):
    return "\t".join(
        [
            row.get("name", ""),
            row.get("signature", ""),
            f"{row.get('page', '')}#{row.get('anchor', '')}",
            row.get("summary", ""),
        ]
    )


def codegen_root_for_tsv(tsv_path):
    if tsv_path.parent.name == "data":
        candidate = tsv_path.parent.parent / "references" / "codegen"
        if candidate.is_dir():
            return candidate
    if tsv_path.parent.name == "codegen":
        return tsv_path.parent
    candidate = tsv_path.parent / "references" / "codegen"
    if candidate.is_dir():
        return candidate
    return DEFAULT_CODEGEN_ROOT


def default_tsv_path():
    if DEFAULT_TSV.is_file():
        return DEFAULT_TSV
    return find_tsv(Path.cwd())


def main(argv=None):
    if hasattr(sys.stdout, "reconfigure"):
        sys.stdout.reconfigure(encoding="utf-8")
    parser = argparse.ArgumentParser(description="Query TSL API reference facts.")
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument("--name", help="exact API/function name")
    group.add_argument("--kw", nargs="+", help="keyword terms (AND)")
    parser.add_argument("--tsv", help="explicit path to function_index.tsv")
    parser.add_argument("--limit", type=int, default=50)
    args = parser.parse_args(argv)

    tsv_path = Path(args.tsv) if args.tsv else default_tsv_path()
    if not tsv_path or not tsv_path.is_file():
        print(
            "ERROR: function_index.tsv not found; reinstall tsl-api-reference "
            "or pass --tsv PATH",
            file=sys.stderr,
        )
        return 1

    rows = load_rows(tsv_path)
    codegen_root = codegen_root_for_tsv(tsv_path)

    if args.name:
        matches = search_exact(rows, args.name)
        if not matches:
            print(f"No TSL API named '{args.name}'. Try: --kw <中文关键词>")
            return 0
        for row in matches:
            body = slice_entry(codegen_root, row["page"], row["signature"])
            if body:
                print(body)
            else:
                print(f"### `{row['signature']}`\n{row.get('summary', '')}")
            print(
                f"\n<!-- {row['scope']}/{row['module']} · "
                f"{row['page']}#{row['anchor']} -->\n"
            )
        return 0

    matches = search_keyword(rows, args.kw)
    print(f"# {len(matches)} matches for: {' '.join(args.kw)}")
    print("name\tsignature\tpage#anchor\tsummary")
    for row in matches[: args.limit]:
        print(format_row(row))
    if len(matches) > args.limit:
        print(f"... {len(matches) - args.limit} more; refine keywords or raise --limit")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
