#!/usr/bin/python3
"""Test the operation of the tinydns utilities."""

import argparse
import dataclasses
import os
import pathlib
import sys
import tempfile

from . import defs
from . import test_conf
from . import test_data
from . import test_edit
from . import test_get
from . import test_run


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

    skip_run_test: bool


def parse_arguments() -> Config:
    """Parse the command-line arguments."""
    parser = argparse.ArgumentParser(prog="tinytest")
    parser.add_argument(
        "-b",
        "--bindir",
        type=pathlib.Path,
        required=True,
        help="the path to the djbdns user tools",
    )
    parser.add_argument(
        "-s",
        "--sbindir",
        type=pathlib.Path,
        required=True,
        help="the path to the djbdns system tools",
    )
    parser.add_argument(
        "-S",
        "--skip-run-test",
        action="store_true",
        help="skip the test that runs tinydns",
    )
    parser.add_argument(
        "-v",
        "--verbose",
        action="store_true",
        help="verbose operation; display diagnostic output",
    )

    args = parser.parse_args()

    subenv = dict(os.environ)
    subenv["LC_ALL"] = "C"
    subenv["LANGUAGE"] = "en"

    return Config(
        bindir=args.bindir,
        sbindir=args.sbindir,
        skip_run_test=args.skip_run_test,
        subenv=subenv,
        verbose=args.verbose,
    )


def run_tests(cfg: Config, tempd: pathlib.Path) -> None:
    """Run some tests."""
    cfg.diag(f"Running tests in {tempd}")
    os.chdir(tempd)

    test_edit.test_tinydns_edit(cfg, tempd)
    test_data.test_tinydns_data(cfg, tempd)
    test_get.test_tinydns_get(cfg, tempd)
    test_conf.test_tinydns_conf(cfg, tempd)

    if not cfg.skip_run_test:
        test_run.test_tinydns_run(cfg, tempd)
        test_run.test_tinydns_run_udp(cfg, tempd)
    else:
        print("\n==== Skipping test_tinydns_run*")

    print("\n==== All fine!")


def main() -> None:
    """Main program: parse options, run the tests."""
    cfg = parse_arguments()
    with tempfile.TemporaryDirectory() as tempd:
        cfg.diag(f"Using temporary directory {tempd}")
        try:
            run_tests(cfg, pathlib.Path(tempd).absolute())
        finally:
            try:
                os.chdir("/")
            except OSError as err:
                print(f"Could not chdir to /: {err}", file=sys.stderr)


if __name__ == "__main__":
    main()
