"""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, cast

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

if TYPE_CHECKING:
    from collections.abc import Sequence

    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,  # ruff:ignore[unused-method-argument]
            values: str | Sequence[Any] | None,  # ruff:ignore[unused-method-argument]
            option_string: str | None = None,  # ruff:ignore[unused-method-argument]
        ) -> None:
            formatter = cast("HelpFormatter", parser._get_formatter())  # ruff:ignore[private-member-access]
            formatter.add_raw_text(get_version_info())
            parser._print_message(formatter.format_help(), sys.stdout)  # ruff:ignore[private-member-access]
            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))
            append_fn = getattr(module, "tox_append_version_info", None)
            info = append_fn() if append_fn is not None else ""
            with_info = f" {info}" if info else ""
            out.append(f"    {egg_info.project_name}-{egg_info.version} at {source}{with_info}")
    inline = MANAGER.inline_module
    if inline is not None:
        source = getattr(inline, "__file__", repr(inline))
        info = inline.tox_append_version_info() if hasattr(inline, "tox_append_version_info") else ""
        with_info = f" {info}" if info else ""
        out.append(f"inline plugin: {source}{with_info}")
    return "\n".join(out)
