#!/usr/bin/env python3
"""Generate per-target Quick Action InfoPlist.strings from a shared source table."""

from __future__ import annotations

import re
import shutil
import sys
from pathlib import Path


ENTRY_PATTERN = re.compile(r'^\s*"((?:[^"\\]|\\.)+)"\s*=\s*"((?:[^"\\]|\\.)*)";\s*$')

TARGETS = {
    "ShichiZipRevealInFileManagerAction": {"variant": "shichizip", "action": "reveal"},
    "ShichiZipOpenInShichiZipAction": {"variant": "shichizip", "action": "open"},
    "ShichiZipCompressAction": {"variant": "shichizip", "action": "compress"},
    "ShichiZipSmartQuickExtractAction": {"variant": "shichizip", "action": "extract"},
    "ShichiZipZSRevealInFileManagerAction": {"variant": "shichizipzs", "action": "reveal"},
    "ShichiZipZSOpenInShichiZipAction": {"variant": "shichizipzs", "action": "open"},
    "ShichiZipZSCompressAction": {"variant": "shichizipzs", "action": "compress"},
    "ShichiZipZSSmartQuickExtractAction": {"variant": "shichizipzs", "action": "extract"},
}


def unescape(text: str) -> str:
    return (
        text.replace(r"\\", "\\")
        .replace(r'\"', '"')
        .replace(r"\n", "\n")
        .replace(r"\t", "\t")
    )


def escape(text: str) -> str:
    return (
        text.replace("\\", r"\\")
        .replace('"', r'\"')
        .replace("\n", r"\n")
        .replace("\t", r"\t")
    )


def render_template(template: str, **values: str) -> str:
    rendered = template
    for key, value in values.items():
        rendered = rendered.replace(f"{{{key}}}", value)
    return rendered


def parse_strings_file(path: Path) -> dict[str, str]:
    values: dict[str, str] = {}
    for raw_line in path.read_text(encoding="utf-8").splitlines():
        line = raw_line.strip()
        if not line or line.startswith("/*") or line.startswith("//"):
            continue

        match = ENTRY_PATTERN.match(raw_line)
        if not match:
            raise ValueError(f"Unsupported .strings syntax in {path}: {raw_line}")

        key, value = match.groups()
        values[unescape(key)] = unescape(value)

    return values


def build_infoplist_content(display_name: str) -> str:
    lines = [
        "/* Generated by project/scripts/generate_quick_action_strings.py. */",
        "/* Do not edit directly. Update project/localization/quick-actions instead. */",
        "",
        f'"CFBundleDisplayName" = "{escape(display_name)}";',
        f'"CFBundleName" = "{escape(display_name)}";',
        "",
    ]
    return "\n".join(lines)


def resolve_value(locale_values: dict[str, str], english_values: dict[str, str], key: str) -> str:
    if key in locale_values:
        return locale_values[key]
    if key in english_values:
        return english_values[key]
    raise KeyError(key)


def resolve_action_text(locale_values: dict[str, str], english_values: dict[str, str], variant: str, action: str) -> str:
    if action == "open":
        open_template = resolve_value(locale_values, english_values, "quickAction.template.openAction")
        app_name = resolve_value(locale_values, english_values, f"quickAction.app.{variant}")
        return render_template(open_template, appName=app_name)

    return resolve_value(locale_values, english_values, f"quickAction.action.{action}")


def resolve_quick_action_title(locale_values: dict[str, str], english_values: dict[str, str], variant: str, action: str) -> str:
    full_template = resolve_value(locale_values, english_values, "quickAction.template.full")
    prefix = resolve_value(locale_values, english_values, f"quickAction.prefix.{variant}")
    action_text = resolve_action_text(locale_values, english_values, variant, action)
    return render_template(full_template, prefix=prefix, action=action_text)


def main() -> int:
    project_root = Path(__file__).resolve().parents[2]
    source_root = project_root / "project" / "localization" / "quick-actions"
    output_root = project_root / "project" / "generated" / "quick-actions"

    english_source = source_root / "en.lproj" / "QuickActions.strings"
    if not english_source.exists():
        print(f"Missing English Quick Action source: {english_source}", file=sys.stderr)
        return 1

    english_values = parse_strings_file(english_source)
    locale_dirs = sorted(path for path in source_root.glob("*.lproj") if path.is_dir())
    if output_root.exists():
        shutil.rmtree(output_root)
    output_root.mkdir(parents=True, exist_ok=True)

    for locale_dir in locale_dirs:
        locale = locale_dir.stem
        locale_source = locale_dir / "QuickActions.strings"
        locale_values = parse_strings_file(locale_source)

        for target_name, target_info in TARGETS.items():
            title = resolve_quick_action_title(
                locale_values,
                english_values,
                target_info["variant"],
                target_info["action"],
            )

            target_dir = output_root / target_name / f"{locale}.lproj"
            target_dir.mkdir(parents=True, exist_ok=True)
            output_path = target_dir / "InfoPlist.strings"
            output_path.write_text(build_infoplist_content(title), encoding="utf-8")

    print(f"Generated Quick Action InfoPlist.strings for {len(locale_dirs)} locale(s)")
    return 0


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