#!/usr/bin/env python3
"""Create XML fixtures for learning 1C form button CommandName storage."""

from __future__ import annotations

import argparse
import json
import shutil
from pathlib import Path


DEFAULT_SOURCE = Path(
    r"\\nas\MST\codex\1C\XML\UPO\Структура базы 1с\Расширения\фс_ДоработкиОбщее\DataProcessors\фс_НастройкаУсловногоОформления\Forms\ТестНастройки\Ext\Form.xml"
)
DEFAULT_OUTPUT_DIR = Path("reports/1c-sql/upo_test/xml-command-binding-fixtures")


VARIANTS = [
    {
        "id": "01-local-button-command-example1",
        "description": "Change only ФормаКомандаОбновить CommandName from КомандаПрименить to КомандаПример1.",
        "replacements": [
            (
                "<Button name=\"ФормаКомандаОбновить\" id=\"15\">\n\t\t\t\t\t\t\t<Type>UsualButton</Type>\n\t\t\t\t\t\t\t<CommandName>Form.Command.КомандаПрименить</CommandName>",
                "<Button name=\"ФормаКомандаОбновить\" id=\"15\">\n\t\t\t\t\t\t\t<Type>UsualButton</Type>\n\t\t\t\t\t\t\t<CommandName>Form.Command.КомандаПример1</CommandName>",
            )
        ],
    },
    {
        "id": "02-standard-button-to-local-command",
        "description": "Change only ТЗИзменитьФорму CommandName from standard CustomizeForm to local КомандаПример1.",
        "replacements": [
            (
                "<Button name=\"ТЗИзменитьФорму\" id=\"57\">\n\t\t\t\t\t\t\t\t\t\t<Type>CommandBarButton</Type>\n\t\t\t\t\t\t\t\t\t\t<CommandName>Form.StandardCommand.CustomizeForm</CommandName>",
                "<Button name=\"ТЗИзменитьФорму\" id=\"57\">\n\t\t\t\t\t\t\t\t\t\t<Type>CommandBarButton</Type>\n\t\t\t\t\t\t\t\t\t\t<CommandName>Form.Command.КомандаПример1</CommandName>",
            )
        ],
    },
    {
        "id": "03-combined-command-binding-switches",
        "description": "Apply both existing-button CommandName changes in one Form.xml.",
        "replacements": [
            (
                "<Button name=\"ФормаКомандаОбновить\" id=\"15\">\n\t\t\t\t\t\t\t<Type>UsualButton</Type>\n\t\t\t\t\t\t\t<CommandName>Form.Command.КомандаПрименить</CommandName>",
                "<Button name=\"ФормаКомандаОбновить\" id=\"15\">\n\t\t\t\t\t\t\t<Type>UsualButton</Type>\n\t\t\t\t\t\t\t<CommandName>Form.Command.КомандаПример1</CommandName>",
            ),
            (
                "<Button name=\"ТЗИзменитьФорму\" id=\"57\">\n\t\t\t\t\t\t\t\t\t\t<Type>CommandBarButton</Type>\n\t\t\t\t\t\t\t\t\t\t<CommandName>Form.StandardCommand.CustomizeForm</CommandName>",
                "<Button name=\"ТЗИзменитьФорму\" id=\"57\">\n\t\t\t\t\t\t\t\t\t\t<Type>CommandBarButton</Type>\n\t\t\t\t\t\t\t\t\t\t<CommandName>Form.Command.КомандаПример1</CommandName>",
            ),
        ],
    },
    {
        "id": "04-add-two-learning-buttons",
        "description": "Add two new usual buttons under Группа2: one local command, one standard command.",
        "replacements": [
            (
                "\t\t\t\t\t\t\t\t<Button name=\"КомандаПример2\" id=\"63\">\n\t\t\t\t\t\t\t\t\t<Type>UsualButton</Type>\n\t\t\t\t\t\t\t\t\t<CommandName>Form.Command.КомандаПример2</CommandName>\n\t\t\t\t\t\t\t\t\t<ExtendedTooltip name=\"КомандаПример2РасширеннаяПодсказка\" id=\"64\"/>\n\t\t\t\t\t\t\t\t</Button>",
                "\t\t\t\t\t\t\t\t<Button name=\"КомандаПример2\" id=\"63\">\n\t\t\t\t\t\t\t\t\t<Type>UsualButton</Type>\n\t\t\t\t\t\t\t\t\t<CommandName>Form.Command.КомандаПример2</CommandName>\n\t\t\t\t\t\t\t\t\t<ExtendedTooltip name=\"КомандаПример2РасширеннаяПодсказка\" id=\"64\"/>\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t<Button name=\"УчебнаяКнопкаКомандаПример1\" id=\"101\">\n\t\t\t\t\t\t\t\t\t<Type>UsualButton</Type>\n\t\t\t\t\t\t\t\t\t<CommandName>Form.Command.КомандаПример1</CommandName>\n\t\t\t\t\t\t\t\t\t<ExtendedTooltip name=\"УчебнаяКнопкаКомандаПример1РасширеннаяПодсказка\" id=\"102\"/>\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t<Button name=\"УчебнаяКнопкаСтандартнаяНастройка\" id=\"103\">\n\t\t\t\t\t\t\t\t\t<Type>UsualButton</Type>\n\t\t\t\t\t\t\t\t\t<CommandName>Form.StandardCommand.CustomizeForm</CommandName>\n\t\t\t\t\t\t\t\t\t<ExtendedTooltip name=\"УчебнаяКнопкаСтандартнаяНастройкаРасширеннаяПодсказка\" id=\"104\"/>\n\t\t\t\t\t\t\t\t</Button>",
            )
        ],
    },
]


def apply_variant(text: str, replacements: list[tuple[str, str]]) -> str:
    result = text
    for old, new in replacements:
        if old not in result:
            raise ValueError(f"Could not find expected XML fragment: {old[:120]!r}")
        result = result.replace(old, new, 1)
    return result


def main() -> int:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--source", type=Path, default=DEFAULT_SOURCE)
    parser.add_argument("--output-dir", type=Path, default=DEFAULT_OUTPUT_DIR)
    args = parser.parse_args()

    source_text = args.source.read_text(encoding="utf-8-sig")
    args.output_dir.mkdir(parents=True, exist_ok=True)
    baseline = args.output_dir / "00-original" / "Form.xml"
    baseline.parent.mkdir(parents=True, exist_ok=True)
    shutil.copyfile(args.source, baseline)

    manifest = {
        "schema": "onec_form_command_binding_xml_fixtures.v1",
        "source": str(args.source),
        "output_dir": str(args.output_dir),
        "baseline": str(baseline),
        "variants": [],
    }
    for variant in VARIANTS:
        variant_dir = args.output_dir / variant["id"]
        variant_dir.mkdir(parents=True, exist_ok=True)
        output = variant_dir / "Form.xml"
        output.write_text(apply_variant(source_text, variant["replacements"]), encoding="utf-8")
        manifest["variants"].append(
            {
                "id": variant["id"],
                "description": variant["description"],
                "form_xml": str(output),
                "replacements": len(variant["replacements"]),
            }
        )

    manifest_path = args.output_dir / "manifest.json"
    manifest_path.write_text(json.dumps(manifest, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
    print(json.dumps({"status": "ok", "manifest": str(manifest_path), "variants": len(VARIANTS)}, ensure_ascii=False, indent=2))
    return 0


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