from __future__ import annotations

import sys
from pathlib import Path
from typing import Any


ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(ROOT))

import scripts.smoke_1c_write_preflight as smoke  # noqa: E402


def test_repository_lock_is_a_valid_preflight_classification() -> None:
    assert smoke.classified_preflight_status("needs_repository_lock") is True
    assert smoke.classified_preflight_status("unexpected") is False


def test_saved_module_target_prefers_bounded_stream(monkeypatch) -> None:
    whole_form = {
        "kind": "module",
        "module_ref": "ConfigCASSave:extension__form.0",
        "file_name": "extension__form.0",
        "module_path": "2",
    }
    bounded_stream = {
        "kind": "module",
        "module_ref": "ConfigSave:module.3#stream:4",
        "file_name": "module.3",
        "stream_index": 4,
    }

    def fake_rpc_call(
        _endpoint_url: str,
        method: str,
        _payload: dict[str, Any],
        _timeout: float,
        *,
        transport: str,
        session_id: str | None,
    ) -> dict[str, Any]:
        assert method == "metadata.saved_state.modules.search"
        assert transport == "rest"
        assert session_id is None
        return {
            "status": "ok",
            "modules": [
                {"streams": [{"write_plan_target": whole_form}]},
                {"streams": [{"write_plan_target": bounded_stream}]},
            ],
        }

    monkeypatch.setattr(smoke, "rpc_call", fake_rpc_call)

    result = smoke.first_saved_module_target(
        "http://adapter",
        "upo_test",
        30,
        transport="rest",
        session_id=None,
    )

    assert result == bounded_stream


def test_public_extension_form_candidate_is_name_first_and_prefers_title() -> None:
    result = smoke.first_public_extension_form_candidate(
        {
            "forms": [
                {
                    "matches": [
                        {
                            "selector": {
                                "extension": "test2",
                                "ref": "Catalog.test2",
                                "form": "t_Форма",
                                "command": "ЗаменаДомена",
                            },
                            "writable_properties": [
                                {
                                    "property": "name",
                                    "presentation": "Имя",
                                    "value": "ЗаменаДомена",
                                    "value_type": "string",
                                },
                                {
                                    "property": "title",
                                    "presentation": "Заголовок",
                                    "value": "Замена домена",
                                    "value_type": "string",
                                },
                            ],
                        }
                    ],
                }
            ]
        }
    )

    assert result == {
        "target": {
            "kind": "form",
            "extension": "test2",
            "ref": "Catalog.test2",
            "form": "t_Форма",
            "command": "ЗаменаДомена",
        },
        "edit": {
            "property": "Заголовок",
            "value": "Замена домена [NAME-FIRST PREFLIGHT]",
        },
    }


def test_public_extension_module_candidate_is_name_first() -> None:
    result = smoke.first_public_extension_module_candidate(
        {
            "modules": [
                {
                    "streams": [
                        {
                            "preview": "\n&НаКлиенте\nПроцедура Команда()\nКонецПроцедуры",
                            "write_plan_target": {
                                "kind": "module",
                                "extension": "test2",
                                "ref": "Catalog.test2",
                                "form": "t_Форма",
                                "module": "Модуль формы",
                                "qualified_name": "test2.t_Форма.Модуль формы",
                                "stream_ordinal": 1,
                            },
                        }
                    ]
                }
            ]
        }
    )

    assert result == {
        "target": {
            "kind": "module",
            "extension": "test2",
            "ref": "Catalog.test2",
            "form": "t_Форма",
            "module": "Модуль формы",
            "qualified_name": "test2.t_Форма.Модуль формы",
            "stream_ordinal": 1,
        },
        "intent": {
            "operation": "replace_with_control",
            "control_fragment": "&НаКлиенте",
            "new": "&НаКлиенте\nПроцедура Команда()\nКонецПроцедуры",
        },
    }


def test_public_extension_module_candidate_rejects_storage_handle() -> None:
    result = smoke.first_public_extension_module_candidate(
        {
            "modules": [
                {
                    "streams": [
                        {
                            "preview": "Процедура Команда()\nКонецПроцедуры",
                            "write_plan_target": {
                                "extension": "test2",
                                "ref": "Catalog.test2",
                                "module": "Модуль формы",
                                "module_ref": "ConfigCASSave:opaque.0",
                            },
                        }
                    ]
                }
            ]
        }
    )

    assert result is None


def test_different_extension_guid_changes_only_last_hex_digit() -> None:
    assert (
        smoke.different_extension_guid(
            "extension:fb26cf42-7609-11f1-828f-005056b0d483"
        )
        == "fb26cf42-7609-11f1-828f-005056b0d480"
    )
    assert (
        smoke.different_extension_guid(
            "extension:fb26cf42-7609-11f1-828f-005056b0d480"
        )
        == "fb26cf42-7609-11f1-828f-005056b0d481"
    )
    assert smoke.different_extension_guid("base") is None


def test_name_first_extension_form_preflight_rejects_base_gate_layer(monkeypatch) -> None:
    def fake_rpc_call(
        _endpoint_url: str,
        method: str,
        payload: dict[str, Any],
        _timeout: float,
        *,
        transport: str,
        session_id: str | None,
    ) -> dict[str, Any]:
        assert transport == "rest"
        assert session_id is None
        if method == "help.methods":
            return {"methods": [{"name": "metadata.write.preflight"}]}
        if method == "metadata.saved_state.modules.search":
            return {"status": "ok", "modules": []}
        if method == "metadata.saved_state.forms.search":
            return {
                "status": "ok",
                "counts": {"forms": 1},
                "forms": [
                    {
                        "matches": [
                            {
                                "selector": {
                                    "extension": "test2",
                                    "ref": "Catalog.test2",
                                    "form": "t_Форма",
                                    "command": "ЗаменаДомена",
                                },
                                "writable_properties": [
                                    {
                                        "property": "title",
                                        "presentation": "Заголовок",
                                        "value": "Замена домена",
                                        "value_type": "string",
                                    }
                                ],
                            }
                        ]
                    }
                ],
            }
        if method == "metadata.write.preflight" and (payload.get("target") or {}).get("extension"):
            return {
                "schema": "onec_metadata_write_preflight.v1",
                "status": "ready",
                "allowed": True,
                "plan": {"status": "planned", "allowed": True},
                "repository": {"layer_id": "base"},
                "support": {"layer_id": "base"},
            }
        return {
            "schema": "onec_metadata_write_preflight.v1",
            "status": "blocked",
            "allowed": False,
            "plan": {"allowed": False},
        }

    monkeypatch.setattr(smoke, "rpc_call", fake_rpc_call)

    report = smoke.run_smoke(
        "http://adapter",
        "upo_test",
        30,
        transport="rest",
        require_name_first_extension_form=True,
    )

    assert report["status"] == "failed"
    assert report["checks"]["name_first_extension_form_preflight"]["name_first"] is True
    assert any("resolved extension GUID layer" in failure for failure in report["failures"])
