"""Common definitions for the tinydns test suite."""

from __future__ import annotations

import dataclasses
import subprocess  # noqa: S404
import typing


if typing.TYPE_CHECKING:
    import pathlib


@dataclasses.dataclass(frozen=True)
class TestRecord:
    """A single test record."""

    rtype: str
    name: str
    address: str
    answers: list[str]


@dataclasses.dataclass(frozen=True)
class RecordType:
    """Metadata about a record type."""

    query: str
    rtype: int
    prefix: str


MINENC = "us-ascii"
SAFEENC = "ISO-8859-1"

SVCDIR = "svc-tinydns"

RECORDS = [
    TestRecord(
        rtype="ns",
        name="example.com",
        address="127.6.16.1",
        answers=[
            "answer: example.com 259200 NS a.ns.example.com",
            "answer: example.com 259200 NS b.ns.example.com",
        ],
    ),
    TestRecord(
        rtype="ns",
        name="example.com",
        address="127.6.16.2",
        answers=[
            "answer: example.com 259200 NS a.ns.example.com",
            "answer: example.com 259200 NS b.ns.example.com",
        ],
    ),
    TestRecord(
        rtype="mx",
        name="example.com",
        address="127.6.16.1",
        answers=["answer: example.com 86400 MX 0 a.mx.example.com"],
    ),
    TestRecord(
        rtype="host",
        name="example.com",
        address="127.6.16.3",
        answers=["answer: example.com 86400 A 127.6.16.3"],
    ),
    TestRecord(
        rtype="alias",
        name="www.example.com",
        address="127.6.16.3",
        answers=["answer: www.example.com 86400 A 127.6.16.3"],
    ),
    TestRecord(
        rtype="childns",
        name="dev.example.com",
        address="127.6.16.17",
        answers=["authority: dev.example.com 259200 NS a.ns.dev.example.com"],
    ),
]

TYPES = {
    "ns": RecordType(query="ns", rtype=2, prefix="."),
    "mx": RecordType(query="mx", rtype=15, prefix="@"),
    "host": RecordType(query="a", rtype=1, prefix="="),
    "alias": RecordType(query="a", rtype=1, prefix="+"),
    "childns": RecordType(query="ns", rtype=2, prefix="&"),
}


@dataclasses.dataclass(frozen=True)
class Config:
    """Runtime configuration for the tinydns test program."""

    bindir: pathlib.Path
    sbindir: pathlib.Path
    subenv: dict[str, str]
    verbose: bool

    def diag(self, msg: str) -> None:
        """Display a diagnostic message if requested."""
        if self.verbose:
            print(f"diag: {msg}")

    def check_call(self, cmd: list[pathlib.Path | str]) -> None:
        """Run a program in a sane environment."""
        subprocess.check_call(cmd, shell=False, env=self.subenv)  # noqa: S603

    def check_output(self, cmd: list[pathlib.Path | str], encoding: str = MINENC) -> str:
        """Return the output of a program run in a sane environment."""
        return subprocess.check_output(  # noqa: S603
            cmd,
            shell=False,
            env=self.subenv,
            encoding=encoding,
        )
