# Copyright 2023 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Generate documentation for `cros query` types in Markdown."""

import dataclasses
import functools
import inspect
import io
from pathlib import Path
import typing
from typing import Any, TextIO

from chromite.format import formatters
from chromite.lib import build_query
from chromite.lib import commandline
from chromite.lib import constants


_DEFAULT_OUTPUT = constants.CHROMITE_DIR / "docs" / "cros-query-types.md"
_QUERY_TARGETS = [
    build_query.Board,
    build_query.Ebuild,
    build_query.Profile,
    build_query.Overlay,
]


def _repr_type(type_: Any) -> str:
    """Format a data type for the markdown document.

    Args:
        type_: A typing annotation.

    Returns:
        A string of how the type should be represented.
    """

    # In Python 3.8 and earlier, we have to hack around to get the type name.
    # This is made easier in Python 3.9+, where __name__ is populated correctly.
    # Once we stop supporting Python 3.8 and earlier, this can be dropped.
    def _get_type_name():
        name = getattr(type_, "__name__", None)
        if name:
            return name

        # This is hacks for Python 3.8 and earlier only.
        # pylint: disable=protected-access
        name = getattr(type_, "_name", None)
        if name:
            return name

        if isinstance(type_, typing.ForwardRef):
            return type_.__forward_arg__

        return type_.__origin__._name

    name = _get_type_name()
    args = typing.get_args(type_)
    if not args:
        return name

    # Python 3.8 and earlier loose track of Optional[T] and store it as
    # Union[T, NoneType].  Translate this back for consistent behavior.
    if name == "Union" and len(args) == 2 and args[1] == type(None):
        name = "Optional"

    # Optional[T] type is weird, and provides args (T, NoneType).  Strip the
    # excess NoneType.
    if name == "Optional":
        args = args[:1]

    return f"{name}[{', '.join(_repr_type(x) for x in args)}]"


def _gen_docs(output: TextIO) -> None:
    """Generate the documentation in Markdown format.

    Args:
        output: The file-like object for the documentation to be written to.
    """

    def _pr(*args, **kwargs) -> None:
        kwargs.setdefault("file", output)
        print(*args, **kwargs)

    def _doc_attr(func, call_anno="", type_anno="") -> None:
        _pr(f"* `{func.__name__}{call_anno}`{type_anno}: {func.__doc__}")

    def _doc_prop(func) -> None:
        return_type = typing.get_type_hints(func).get("return")
        _doc_attr(func, type_anno=f" (`{_repr_type(return_type)}`)")

    _pr("<!-- This file is auto-generated!  Do not edit by hand. -->")
    _pr("<!-- To update, run chromite/scripts/generate_query_docs. -->")
    _pr()
    _pr("# `cros query` Target Types")

    for target in _QUERY_TARGETS:
        _pr()
        _pr(f"## {target.__name__}")
        _pr()
        _pr("**Attributes:**")
        _pr()

        dataclass_attrs = set()
        if dataclasses.is_dataclass(target):
            for field in dataclasses.fields(target):
                _pr(f"* `{field.name}` (`{field.type}`)")
                dataclass_attrs.add(field.name)

        for attr in sorted(dir(target)):
            if attr in dataclass_attrs:
                continue
            if attr.startswith("_"):
                continue
            # tree() is considered internal to the CLI.
            if attr == "tree":
                continue
            method = getattr(target, attr)
            if not method.__doc__:
                continue
            if inspect.ismethod(method):
                # We expect unbound methods (i.e., function attributes), not
                # bound methods (which are likely a classmethod).  Skip bound
                # methods.
                continue
            if isinstance(method, property):
                _doc_prop(method.fget)
            elif isinstance(method, functools.cached_property):
                _doc_prop(method.func)
            else:
                hints = typing.get_type_hints(method)
                return_type = hints.pop("return")
                args = ", ".join(
                    f"{k}: {_repr_type(v)}" for k, v in hints.items()
                )
                call_anno = f"({args}) -> {_repr_type(return_type)}"
                _doc_attr(method, call_anno=call_anno)


def _parse_args(argv):
    parser = commandline.ArgumentParser(description=__doc__)
    parser.add_argument(
        "-o",
        "--output-file",
        type=Path,
        default=_DEFAULT_OUTPUT,
        help="Path to write markdown",
    )
    return parser.parse_args(argv)


def main(argv) -> None:
    args = _parse_args(argv)
    buf = io.StringIO()
    _gen_docs(buf)
    contents = formatters.whitespace.Data(buf.getvalue(), path=args.output_file)
    args.output_file.write_text(contents, encoding="utf-8")
