#!/usr/bin/env python3
"""Copy a documentation recipe and link to it from the source recipe."""
import argparse
import html
import json
from pathlib import Path
import re
import tempfile


def replace_once(text, pattern, replacement, description):
    result, count = re.subn(pattern, replacement, text, count=1)
    if count != 1:
        raise ValueError("Template has no unique " + description)
    return result


def clone(site, template, name, title, lead):
    if not re.fullmatch(r"[a-z0-9]+(?:-[a-z0-9]+)*", name):
        raise ValueError("The new name must use lowercase letters, numbers and hyphens.")
    source = site / "examples" / (template + ".html")
    destination = site / "examples" / (name + ".html")
    if destination.exists():
        raise FileExistsError("Refusing to overwrite " + str(destination))
    original = source.read_text()
    markup = original
    if 'assets/docs-recipes.css' not in markup or 'assets/docs-recipes.js' not in markup:
        raise ValueError("Choose a documentation recipe with both shared dependencies.")
    escaped_title = html.escape(title)
    markup = replace_once(markup, r"<title>[^<]*</title>", lambda _: "<title>" + escaped_title + " · Local TypeSafe extension</title>", "document title")
    markup = replace_once(markup, r"(<h1\b[^>]*>)[\s\S]*?(</h1>)", lambda match: match[1] + escaped_title + match[2], "page heading")
    markup = replace_once(markup, r'(<div class="dr-mobile-trail">[\s\S]*?<strong>)[\s\S]*?(</strong>)', lambda match: match[1] + escaped_title + match[2], "mobile page label")
    markup = replace_once(markup, r'(data-component="docs-article-header"[^>]*>[\s\S]*?</h1>\s*<p>)[\s\S]*?(</p>)', lambda match: match[1] + html.escape(lead) + match[2], "page lead")
    markup = markup.replace(' aria-current="page"', '')
    markup = markup.replace('class="current"', 'class="dr-cloned-nav-link"')
    own_link = '<p>LOCAL EXTENSION</p><a class="current" aria-current="page" href="' + name + '.html">' + escaped_title + '</a>'
    markup = replace_once(markup, r'(<aside\b[^>]*\bid="dr-sidebar"[\s\S]*?)(</aside>)', lambda match: match[1] + own_link + match[2], "documentation navigation")
    markup = replace_once(markup, r'<body\b', lambda _: '<body data-cloned-from="' + template + '.html"', "body")
    incoming_link = '<p>LOCAL EXTENSION</p><a href="' + name + '.html">' + escaped_title + '</a>'
    linked_source = replace_once(original, r'(<aside\b[^>]*\bid="dr-sidebar"[\s\S]*?)(</aside>)', lambda match: match[1] + incoming_link + match[2], "source navigation")
    # Validate both outputs before writing. An existing route is the entry point
    # for the new page; its own current-page marker cannot provide discovery.
    with destination.open("x") as target:
        target.write(markup)
    staged_source = None
    try:
        with tempfile.NamedTemporaryFile(mode="w", dir=source.parent, prefix=source.name + ".", delete=False) as target:
            staged_source = Path(target.name)
            target.write(linked_source)
        staged_source.chmod(source.stat().st_mode)
        staged_source.replace(source)
    except OSError:
        destination.unlink()
        raise
    finally:
        if staged_source and staged_source.exists():
            staged_source.unlink()
    return destination


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--template", required=True, choices=["docs-intro", "quickstart", "score", "python-api", "cookbook", "smart-home"])
    parser.add_argument("--name", required=True, help="New filename stem, such as sdk-errors")
    parser.add_argument("--title", required=True)
    parser.add_argument("--lead", default="Original local extension built from the public TypeSafe documentation reference.")
    parser.add_argument("--site", type=Path, help="Static site root; inferred when run from tools or downloads")
    args = parser.parse_args()
    directory = Path(__file__).resolve().parents[1]
    site = args.site or (directory if (directory / "examples").is_dir() else directory / "site")
    destination = clone(site.resolve(), args.template, args.name, args.title, args.lead)
    print(json.dumps({"created": str(destination), "template": args.template, "discoveryFrom": str(site.resolve() / "examples" / (args.template + ".html")), "next": "Edit the intended content or component inside the retained shell. Start from the source recipe's new navigation link, then verify inherited behavior plus the new requirements. Add the route to the shared search registry if it should appear in search."}, indent=2))


if __name__ == "__main__":
    main()
