#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0
# -*- coding: utf-8; mode: python -*-

"""
    Script to auto generate the documentation for Netlink specifications.

    :copyright:  Copyright (C) 2023  Breno Leitao <leitao@debian.org>
    :license:    GPL Version 2, June 1991 see linux/COPYING for details.

    This script performs extensive parsing to the Linux kernel's netlink YAML
    spec files, in an effort to avoid needing to heavily mark up the original
    YAML file.

    This code is split in three big parts:
        1) RST formatters: Use to convert a string to a RST output
        2) Parser helpers: Functions to parse the YAML data structure
        3) Main function and small helpers
"""

from typing import Any, Dict, List
import os.path
import sys
import argparse
import logging
import yaml


SPACE_PER_LEVEL = 4


# RST Formatters
# ==============
def headroom(level: int) -> str:
    """Return space to format"""
    return " " * (level * SPACE_PER_LEVEL)


def bold(text: str) -> str:
    """Format bold text"""
    return f"**{text}**"


def inline(text: str) -> str:
    """Format inline text"""
    return f"``{text}``"


def sanitize(text: str) -> str:
    """Remove newlines and multiple spaces"""
    # This is useful for some fields that are spread across multiple lines
    return str(text).replace("\n", "").strip()


def rst_fields(key: str, value: str, level: int = 0) -> str:
    """Return a RST formatted field"""
    return headroom(level) + f":{key}: {value}"


def rst_definition(key: str, value: Any, level: int = 0) -> str:
    """Format a single rst definition"""
    return headroom(level) + key + "\n" + headroom(level + 1) + str(value)


def rst_paragraph(paragraph: str, level: int = 0) -> str:
    """Return a formatted paragraph"""
    return headroom(level) + paragraph


def rst_bullet(item: str, level: int = 0) -> str:
    """Return a formatted a bullet"""
    return headroom(level) + f"- {item}"


def rst_subsection(title: str) -> str:
    """Add a sub-section to the document"""
    return f"{title}\n" + "-" * len(title)


def rst_subsubsection(title: str) -> str:
    """Add a sub-sub-section to the document"""
    return f"{title}\n" + "~" * len(title)


def rst_section(title: str) -> str:
    """Add a section to the document"""
    return f"\n{title}\n" + "=" * len(title)


def rst_subtitle(title: str) -> str:
    """Add a subtitle to the document"""
    return "\n" + "-" * len(title) + f"\n{title}\n" + "-" * len(title) + "\n\n"


def rst_title(title: str) -> str:
    """Add a title to the document"""
    return "=" * len(title) + f"\n{title}\n" + "=" * len(title) + "\n\n"


def rst_list_inline(list_: List[str], level: int = 0) -> str:
    """Format a list using inlines"""
    return headroom(level) + "[" + ", ".join(inline(i) for i in list_) + "]"


def rst_header() -> str:
    """The headers for all the auto generated RST files"""
    lines = []

    lines.append(rst_paragraph(".. SPDX-License-Identifier: GPL-2.0"))
    lines.append(rst_paragraph(".. NOTE: This document was auto-generated.\n\n"))

    return "\n".join(lines)


def rst_toctree(maxdepth: int = 2) -> str:
    """Generate a toctree RST primitive"""
    lines = []

    lines.append(".. toctree::")
    lines.append(f"   :maxdepth: {maxdepth}\n\n")

    return "\n".join(lines)


def rst_label(title: str) -> str:
    """Return a formatted label"""
    return f".. _{title}:\n\n"


# Parsers
# =======


def parse_mcast_group(mcast_group: List[Dict[str, Any]]) -> str:
    """Parse 'multicast' group list and return a formatted string"""
    lines = []
    for group in mcast_group:
        lines.append(rst_bullet(group["name"]))

    return "\n".join(lines)


def parse_do(do_dict: Dict[str, Any], level: int = 0) -> str:
    """Parse 'do' section and return a formatted string"""
    lines = []
    for key in do_dict.keys():
        lines.append(rst_paragraph(bold(key), level + 1))
        lines.append(parse_do_attributes(do_dict[key], level + 1) + "\n")

    return "\n".join(lines)


def parse_do_attributes(attrs: Dict[str, Any], level: int = 0) -> str:
    """Parse 'attributes' section"""
    if "attributes" not in attrs:
        return ""
    lines = [rst_fields("attributes", rst_list_inline(attrs["attributes"]), level + 1)]

    return "\n".join(lines)


def parse_operations(operations: List[Dict[str, Any]]) -> str:
    """Parse operations block"""
    preprocessed = ["name", "doc", "title", "do", "dump"]
    lines = []

    for operation in operations:
        lines.append(rst_section(operation["name"]))
        lines.append(rst_paragraph(sanitize(operation["doc"])) + "\n")

        for key in operation.keys():
            if key in preprocessed:
                # Skip the special fields
                continue
            lines.append(rst_fields(key, operation[key], 0))

        if "do" in operation:
            lines.append(rst_paragraph(":do:", 0))
            lines.append(parse_do(operation["do"], 0))
        if "dump" in operation:
            lines.append(rst_paragraph(":dump:", 0))
            lines.append(parse_do(operation["dump"], 0))

        # New line after fields
        lines.append("\n")

    return "\n".join(lines)


def parse_entries(entries: List[Dict[str, Any]], level: int) -> str:
    """Parse a list of entries"""
    ignored = ["pad"]
    lines = []
    for entry in entries:
        if isinstance(entry, dict):
            # entries could be a list or a dictionary
            field_name = entry.get("name", "")
            if field_name in ignored:
                continue
            type_ = entry.get("type")
            if type_:
                field_name += f" ({inline(type_)})"
            lines.append(
                rst_fields(field_name, sanitize(entry.get("doc", "")), level)
            )
        elif isinstance(entry, list):
            lines.append(rst_list_inline(entry, level))
        else:
            lines.append(rst_bullet(inline(sanitize(entry)), level))

    lines.append("\n")
    return "\n".join(lines)


def parse_definitions(defs: Dict[str, Any]) -> str:
    """Parse definitions section"""
    preprocessed = ["name", "entries", "members"]
    ignored = ["render-max"]  # This is not printed
    lines = []

    for definition in defs:
        lines.append(rst_section(definition["name"]))
        for k in definition.keys():
            if k in preprocessed + ignored:
                continue
            lines.append(rst_fields(k, sanitize(definition[k]), 0))

        # Field list needs to finish with a new line
        lines.append("\n")
        if "entries" in definition:
            lines.append(rst_paragraph(":entries:", 0))
            lines.append(parse_entries(definition["entries"], 1))
        if "members" in definition:
            lines.append(rst_paragraph(":members:", 0))
            lines.append(parse_entries(definition["members"], 1))

    return "\n".join(lines)


def parse_attr_sets(entries: List[Dict[str, Any]]) -> str:
    """Parse attribute from attribute-set"""
    preprocessed = ["name", "type"]
    ignored = ["checks"]
    lines = []

    for entry in entries:
        lines.append(rst_section(entry["name"]))
        for attr in entry["attributes"]:
            type_ = attr.get("type")
            attr_line = attr["name"]
            if type_:
                # Add the attribute type in the same line
                attr_line += f" ({inline(type_)})"

            lines.append(rst_subsubsection(attr_line))

            for k in attr.keys():
                if k in preprocessed + ignored:
                    continue
                lines.append(rst_fields(k, sanitize(attr[k]), 0))
            lines.append("\n")

    return "\n".join(lines)


def parse_sub_messages(entries: List[Dict[str, Any]]) -> str:
    """Parse sub-message definitions"""
    lines = []

    for entry in entries:
        lines.append(rst_section(entry["name"]))
        for fmt in entry["formats"]:
            value = fmt["value"]

            lines.append(rst_bullet(bold(value)))
            for attr in ['fixed-header', 'attribute-set']:
                if attr in fmt:
                    lines.append(rst_fields(attr, fmt[attr], 1))
            lines.append("\n")

    return "\n".join(lines)


def parse_yaml(obj: Dict[str, Any]) -> str:
    """Format the whole YAML into a RST string"""
    lines = []

    # Main header

    lines.append(rst_header())

    title = f"Family ``{obj['name']}`` netlink specification"
    lines.append(rst_title(title))
    lines.append(rst_paragraph(".. contents::\n"))

    if "doc" in obj:
        lines.append(rst_subtitle("Summary"))
        lines.append(rst_paragraph(obj["doc"], 0))

    # Operations
    if "operations" in obj:
        lines.append(rst_subtitle("Operations"))
        lines.append(parse_operations(obj["operations"]["list"]))

    # Multicast groups
    if "mcast-groups" in obj:
        lines.append(rst_subtitle("Multicast groups"))
        lines.append(parse_mcast_group(obj["mcast-groups"]["list"]))

    # Definitions
    if "definitions" in obj:
        lines.append(rst_subtitle("Definitions"))
        lines.append(parse_definitions(obj["definitions"]))

    # Attributes set
    if "attribute-sets" in obj:
        lines.append(rst_subtitle("Attribute sets"))
        lines.append(parse_attr_sets(obj["attribute-sets"]))

    # Sub-messages
    if "sub-messages" in obj:
        lines.append(rst_subtitle("Sub-messages"))
        lines.append(parse_sub_messages(obj["sub-messages"]))

    return "\n".join(lines)


# Main functions
# ==============


def parse_arguments() -> argparse.Namespace:
    """Parse arguments from user"""
    parser = argparse.ArgumentParser(description="Netlink RST generator")

    parser.add_argument("-v", "--verbose", action="store_true")
    parser.add_argument("-o", "--output", help="Output file name")

    # Index and input are mutually exclusive
    group = parser.add_mutually_exclusive_group()
    group.add_argument(
        "-x", "--index", action="store_true", help="Generate the index page"
    )
    group.add_argument("-i", "--input", help="YAML file name")

    args = parser.parse_args()

    if args.verbose:
        logging.basicConfig(level=logging.DEBUG)

    if args.input and not os.path.isfile(args.input):
        logging.warning("%s is not a valid file.", args.input)
        sys.exit(-1)

    if not args.output:
        logging.error("No output file specified.")
        sys.exit(-1)

    if os.path.isfile(args.output):
        logging.debug("%s already exists. Overwriting it.", args.output)

    return args


def parse_yaml_file(filename: str) -> str:
    """Transform the YAML specified by filename into a rst-formmated string"""
    with open(filename, "r", encoding="utf-8") as spec_file:
        yaml_data = yaml.safe_load(spec_file)
        content = parse_yaml(yaml_data)

    return content


def write_to_rstfile(content: str, filename: str) -> None:
    """Write the generated content into an RST file"""
    logging.debug("Saving RST file to %s", filename)

    with open(filename, "w", encoding="utf-8") as rst_file:
        rst_file.write(content)


def generate_main_index_rst(output: str) -> None:
    """Generate the `networking_spec/index` content and write to the file"""
    lines = []

    lines.append(rst_header())
    lines.append(rst_label("specs"))
    lines.append(rst_title("Netlink Family Specifications"))
    lines.append(rst_toctree(1))

    index_dir = os.path.dirname(output)
    logging.debug("Looking for .rst files in %s", index_dir)
    for filename in sorted(os.listdir(index_dir)):
        if not filename.endswith(".rst") or filename == "index.rst":
            continue
        lines.append(f"   {filename.replace('.rst', '')}\n")

    logging.debug("Writing an index file at %s", output)
    write_to_rstfile("".join(lines), output)


def main() -> None:
    """Main function that reads the YAML files and generates the RST files"""

    args = parse_arguments()

    if args.input:
        logging.debug("Parsing %s", args.input)
        try:
            content = parse_yaml_file(os.path.join(args.input))
        except Exception as exception:
            logging.warning("Failed to parse %s.", args.input)
            logging.warning(exception)
            sys.exit(-1)

        write_to_rstfile(content, args.output)

    if args.index:
        # Generate the index RST file
        generate_main_index_rst(args.output)


if __name__ == "__main__":
    main()
