from __future__ import annotations

from pathlib import Path

import pytest

from rimpack.core.modpack import (
    ActivationReference,
    ActivationRule,
    ActivationRulesDocument,
    ActivationTomlError,
    load_activation_toml,
    parse_activation_toml,
)


def test_parse_activation_toml_with_supported_rule_shapes() -> None:
    source = """\
[[rules]]
mod = "packageid:author.patch"
when_all_present = [
  "packageid:author.core",
  "packageid:author.addon",
]
when_all_absent = [
  "packageid:author.conflict",
]
reason = "Patch only applies with the supported set"

[[rules]]
mod = "local:AltPatch"
when_any_present = [
  "steam:123456",
  "packageid:author.addon",
]
when_any_absent = [
  "local:OldPatch",
]
enabled = false
"""
    document = parse_activation_toml(source)

    assert document == ActivationRulesDocument(
        rules=(
            ActivationRule(
                mod=ActivationReference(kind="packageid", value="author.patch"),
                when_all_present=(
                    ActivationReference(kind="packageid", value="author.core"),
                    ActivationReference(kind="packageid", value="author.addon"),
                ),
                when_all_absent=(
                    ActivationReference(kind="packageid", value="author.conflict"),
                ),
                reason="Patch only applies with the supported set",
            ),
            ActivationRule(
                mod=ActivationReference(kind="local", value="AltPatch"),
                when_any_present=(
                    ActivationReference(kind="steam", value="123456"),
                    ActivationReference(kind="packageid", value="author.addon"),
                ),
                when_any_absent=(
                    ActivationReference(kind="local", value="OldPatch"),
                ),
                enabled=False,
            ),
        ),
        source_text=source,
    )


def test_parse_empty_activation_toml_document() -> None:
    document = parse_activation_toml("# no activation overrides yet\n")

    assert document == ActivationRulesDocument(
        rules=(),
        source_text="# no activation overrides yet\n",
    )


def test_load_activation_toml_from_path() -> None:
    path = Path("tests") / "__tmp_activation.toml"
    try:
        _ = path.write_text(
            """\
[[rules]]
mod = "packageid:author.patch"
when_all_present = ["packageid:author.core"]
""",
            encoding="utf-8",
        )

        document = load_activation_toml(path)

        assert document.rules == (
            ActivationRule(
                mod=ActivationReference(kind="packageid", value="author.patch"),
                when_all_present=(
                    ActivationReference(kind="packageid", value="author.core"),
                ),
            ),
        )
        assert document.source_path == path
    finally:
        path.unlink(missing_ok=True)


def test_reject_invalid_activation_rule_shapes() -> None:
    with pytest.raises(
        ActivationTomlError,
        match=r"must include at least one activation condition field",
    ):
        _ = parse_activation_toml(
            """\
[[rules]]
mod = "packageid:author.patch"
""",
        )

    with pytest.raises(
        ActivationTomlError,
        match=r"field 'when_all_present' must be an array of strings",
    ):
        _ = parse_activation_toml(
            """\
[[rules]]
mod = "packageid:author.patch"
when_all_present = "packageid:author.core"
""",
        )

    with pytest.raises(
        ActivationTomlError,
        match=r"field 'mod' has unsupported mod reference",
    ):
        _ = parse_activation_toml(
            """\
[[rules]]
mod = "name:author.patch"
when_all_present = ["packageid:author.core"]
""",
        )

    with pytest.raises(
        ActivationTomlError,
        match=r"unsupported top-level keys: metadata",
    ):
        _ = parse_activation_toml(
            """\
metadata = "future"
""",
        )
