"""Display the version information about tox."""

from __future__ import annotations

import sys
from argparse import SUPPRESS, Action, ArgumentParser, Namespace
from pathlib import Path
from typing import TYPE_CHECKING, Any, Sequence, cast

import tox
from tox.plugin import impl
from tox.plugin.manager import MANAGER
from tox.version import version

if TYPE_CHECKING:
    from tox.config.cli.parser import HelpFormatter, ToxParser


@impl
def tox_add_option(parser: ToxParser) -> None:
    class _V(Action):
        def __init__(self, option_strings: Sequence[str], dest: str = SUPPRESS) -> None:
            help_msg = "show program's and plugins version number and exit"
            super().__init__(option_strings=option_strings, dest=dest, nargs=0, help=help_msg, default=SUPPRESS)

        def __call__(
            self,
            parser: ArgumentParser,
            namespace: Namespace,  # noqa: ARG002
            values: str | Sequence[Any] | None,  # noqa: ARG002
            option_string: str | None = None,  # noqa: ARG002
        ) -> None:
            formatter = cast("HelpFormatter", parser._get_formatter())  # noqa: SLF001
            formatter.add_raw_text(get_version_info())
            parser._print_message(formatter.format_help(), sys.stdout)  # noqa: SLF001
            parser.exit()

    parser.add_argument("--version", action=_V)


def get_version_info() -> str:
    out = [f"{version} from {Path(tox.__file__).absolute()}"]
    plugin_info = MANAGER.manager.list_plugin_distinfo()
    if plugin_info:
        out.append("registered plugins:")
        for module, egg_info in plugin_info:
            source = getattr(module, "__file__", repr(module))
            info = module.tox_append_version_info() if hasattr(module, "tox_append_version_info") else ""
            with_info = f" {info}" if info else ""
            out.append(f"    {egg_info.project_name}-{egg_info.version} at {source}{with_info}")
    return "\n".join(out)
