#!/usr/bin/env python3
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
#
# Usage:
#   run './build_docs.py' to generate the documentation and keep it updated
#   open 'http://localhost:1313/' to check live update (this opens the top
#   level index page). you can also directly access a specific document by
#   accessing 'http://localhost:1313/path/to/doc',
#       e.g. http://localhost:1313/hw/ip/uart/doc

import argparse
import logging
import os
import platform
import re
import socket
import subprocess
import sys
import textwrap
from pathlib import Path

import check_tool_requirements
import dashboard.gen_dashboard_entry as gen_dashboard_entry
import difgen.gen_dif_listing as gen_dif_listing
import dvsim.Testplan as Testplan
import reggen.gen_cfg_html as gen_cfg_html
import reggen.gen_html as gen_html
import reggen.gen_selfdoc as reggen_selfdoc
import tlgen
from reggen.ip_block import IpBlock

USAGE = """
  build_docs [options]
"""

# Version of hugo extended to be used to build the docs
try:
    TOOL_REQUIREMENTS = check_tool_requirements.read_tool_requirements()
    HUGO_EXTENDED_VERSION = TOOL_REQUIREMENTS['hugo_extended'].min_version
except Exception as e:
    print("Unable to get required hugo version: %s" % str(e), file=sys.stderr)
    sys.exit(1)

# Configurations
# TODO: Move to config.yaml
SRCTREE_TOP = Path(__file__).parent.joinpath('..').resolve()
config = {
    # Toplevel source directory
    "topdir":
    SRCTREE_TOP,

    # Pre-generate register and hwcfg fragments from these files.
    "hardware_definitions": [
        "hw/ip/aes/data/aes.hjson",
        "hw/ip/aon_timer/data/aon_timer.hjson",
        "hw/top_earlgrey/ip_autogen/alert_handler/data/alert_handler.hjson",
        "hw/ip/entropy_src/data/entropy_src.hjson",
        "hw/ip/csrng/data/csrng.hjson",
        "hw/ip/adc_ctrl/data/adc_ctrl.hjson",
        "hw/ip/edn/data/edn.hjson",
        "hw/ip/flash_ctrl/data/flash_ctrl.hjson",
        "hw/ip/gpio/data/gpio.hjson",
        "hw/ip/hmac/data/hmac.hjson",
        "hw/ip/i2c/data/i2c.hjson",
        "hw/ip/keymgr/data/keymgr.hjson",
        "hw/ip/kmac/data/kmac.hjson",
        "hw/ip/lc_ctrl/data/lc_ctrl.hjson",
        "hw/ip/otbn/data/otbn.hjson",
        "hw/ip/otp_ctrl/data/otp_ctrl.hjson",
        "hw/ip/pattgen/data/pattgen.hjson",
        "hw/ip/pwm/data/pwm.hjson",
        "hw/ip/rom_ctrl/data/rom_ctrl.hjson",
        "hw/ip/rv_dm/data/rv_dm.hjson",
        "hw/top_earlgrey/ip/pinmux/data/autogen/pinmux.hjson",
        "hw/top_earlgrey/ip/clkmgr/data/autogen/clkmgr.hjson",
        "hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr.hjson",
        "hw/top_earlgrey/ip/rstmgr/data/autogen/rstmgr.hjson",
        "hw/top_earlgrey/ip/sensor_ctrl/data/sensor_ctrl.hjson",
        "hw/top_earlgrey/ip_autogen/rv_plic/data/rv_plic.hjson",
        "hw/ip/rv_core_ibex/data/rv_core_ibex.hjson",
        "hw/ip/rv_timer/data/rv_timer.hjson",
        "hw/ip/spi_host/data/spi_host.hjson",
        "hw/ip/spi_device/data/spi_device.hjson",
        "hw/ip/sram_ctrl/data/sram_ctrl.hjson",
        "hw/ip/sysrst_ctrl/data/sysrst_ctrl.hjson",
        "hw/ip/uart/data/uart.hjson",
        "hw/ip/usbdev/data/usbdev.hjson",
    ],

    # Pre-generate dashboard fragments from these directories.
    "dashboard_definitions": {
        "comportable": [
            "hw/ip",
        ],
        "top_earlgrey": [
            "hw/top_earlgrey/ip",
            "hw/top_earlgrey/ip_autogen",
        ],
    },

    # Pre-generate testplan fragments from these files.
    "testplan_definitions": [
        "hw/ip/aes/data/aes_testplan.hjson",
        "hw/top_earlgrey/ip_autogen/alert_handler/data/alert_handler_testplan.hjson",
        "hw/ip/aon_timer/data/aon_timer_testplan.hjson",
        "hw/ip/clkmgr/data/clkmgr_testplan.hjson",
        "hw/ip/entropy_src/data/entropy_src_testplan.hjson",
        "hw/ip/csrng/data/csrng_testplan.hjson",
        "hw/ip/adc_ctrl/data/adc_ctrl_testplan.hjson",
        "hw/ip/edn/data/edn_testplan.hjson",
        "hw/ip/flash_ctrl/data/flash_ctrl_testplan.hjson",
        "hw/ip/gpio/data/gpio_testplan.hjson",
        "hw/ip/hmac/data/hmac_testplan.hjson",
        "hw/ip/i2c/data/i2c_testplan.hjson",
        "hw/ip/kmac/data/kmac_base_testplan.hjson",
        "hw/ip/keymgr/data/keymgr_testplan.hjson",
        "hw/ip/lc_ctrl/data/lc_ctrl_testplan.hjson",
        "hw/ip/otbn/data/otbn_testplan.hjson",
        "hw/ip/otp_ctrl/data/otp_ctrl_testplan.hjson",
        "hw/ip/pattgen/data/pattgen_testplan.hjson",
        "hw/ip/pinmux/data/pinmux_fpv_testplan.hjson",
        "hw/ip/pwm/data/pwm_testplan.hjson",
        "hw/ip/pwrmgr/data/pwrmgr_testplan.hjson",
        "hw/ip/rom_ctrl/data/rom_ctrl_testplan.hjson",
        "hw/ip/rstmgr/data/rstmgr_testplan.hjson",
        "hw/ip/rv_dm/data/rv_dm_testplan.hjson",
        "hw/top_earlgrey/ip_autogen/rv_plic/data/rv_plic_fpv_testplan.hjson",
        "hw/ip/rv_timer/data/rv_timer_testplan.hjson",
        "hw/ip/spi_device/data/spi_device_testplan.hjson",
        "hw/ip/spi_host/data/spi_host_testplan.hjson",
        "hw/ip/sram_ctrl/data/sram_ctrl_base_testplan.hjson",
        "hw/ip/tlul/data/tlul_testplan.hjson",
        "hw/ip/uart/data/uart_testplan.hjson",
        "hw/ip/usbdev/data/usbdev_testplan.hjson",
        "hw/ip/sysrst_ctrl/data/sysrst_ctrl_testplan.hjson",
        "hw/top_earlgrey/data/chip_testplan.hjson",
        "hw/top_earlgrey/data/chip_testplan.hjson:gls",
        "hw/top_earlgrey/data/standalone_sw_testplan.hjson",
        "util/dvsim/examples/testplanner/foo_testplan.hjson",
    ],

    # Pre-generated utility selfdoc
    "selfdoc_tools": ["tlgen", "reggen"],

    # DIF Docs
    "difs-directory": "sw/device/lib/dif",

    # Top Level Docs
    "top_docs_directory": "top",

    # Pre-generate top level documentation from the following files.
    "hw_top_definitions": [
        "hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson",
    ],

    # Output directory for documents
    "outdir":
    SRCTREE_TOP.joinpath('build', 'docs'),
    "outdir-generated":
    SRCTREE_TOP.joinpath('build', 'docs-generated'),
    "verbose":
    False,
}


def generate_dashboards():
    for dashboard_name, dirs in config["dashboard_definitions"].items():
        hjson_paths = []
        for d in dirs:
            hjson_paths += SRCTREE_TOP.joinpath(d).rglob('*.prj.hjson')

        hjson_paths.sort(key=lambda f: f.name)

        dashboard_path = config["outdir-generated"].joinpath(
            dashboard_name, 'dashboard')
        dashboard_path.parent.mkdir(exist_ok=True, parents=True)
        dashboard_html = open(str(dashboard_path), mode='w')
        for hjson_path in hjson_paths:
            gen_dashboard_entry.gen_dashboard_html(hjson_path, dashboard_html)
        dashboard_html.close()


def generate_hardware_blocks():
    for hardware in config["hardware_definitions"]:
        regs = IpBlock.from_path(str(SRCTREE_TOP.joinpath(hardware)), [])

        hw_path = config["outdir-generated"].joinpath(hardware)
        dst_path = hw_path.parent
        dst_path.mkdir(parents=True, exist_ok=True)

        regs_path = dst_path.joinpath(hw_path.name + '.registers')
        with open(regs_path, 'w') as regs_file:
            gen_html.gen_html(regs, regs_file)

        hwcfg_path = dst_path.joinpath(hw_path.name + '.hwcfg')
        with open(hwcfg_path, 'w') as hwcfg_file:
            gen_cfg_html.gen_cfg_html(regs, hwcfg_file)


def generate_testplans():
    for testplan in config["testplan_definitions"]:
        # Split the filename into filename and tags, if provided.
        split = testplan.split(":")
        filename = split[0]
        tags = "_".join(split[1:])
        plan = Testplan.Testplan(SRCTREE_TOP.joinpath(testplan),
                                 repo_top=SRCTREE_TOP)
        plan_filename = f"{filename}.{tags}_testplan"
        plan_path = config["outdir-generated"].joinpath(plan_filename)
        plan_path.parent.mkdir(parents=True, exist_ok=True)

        testplan_html = open(str(plan_path), mode='w')
        testplan_html.write(plan.get_testplan_table("html"))
        testplan_html.close()


def generate_selfdocs():
    """Generate documents for the tools in `util/` if `--doc` option exists.

    Each tool creates selfdoc differently. Manually invoked.
    """
    for tool in config["selfdoc_tools"]:
        selfdoc_path = config["outdir-generated"].joinpath(tool + '.selfdoc')
        selfdoc_path.parent.mkdir(parents=True, exist_ok=True)
        with open(str(selfdoc_path), mode='w') as fout:
            if tool == "reggen":
                reggen_selfdoc.document(fout)
            elif tool == "tlgen":
                fout.write(tlgen.selfdoc(heading=3, cmd='tlgen.py --doc'))


def generate_pkg_reqs():
    """Generate an apt/yum command line invocation from
    apt/yum-requirements.txt

    This will be saved in outdir-generated/apt_cmd.txt and
    outdir-generated/yum_cmd.txt, respectively.
    """

    for pkgmgr in ["apt", "yum"]:
        # Read the apt/yum-requirements.txt
        requirements = []
        requirements_file = open(str(SRCTREE_TOP.joinpath(pkgmgr + "-requirements.txt")))
        for package_line in requirements_file.readlines():
            # Ignore everything after `#` on each line, and strip whitespace
            package = package_line.split('#', 1)[0].strip()
            if package:
                # only add non-empty lines to packages
                requirements.append(package)

        cmd = "$ sudo " + pkgmgr + " install " + " ".join(requirements)
        cmd_lines = textwrap.wrap(cmd,
                                  width=78,
                                  replace_whitespace=True,
                                  subsequent_indent='    ')
        # Newlines need to be escaped
        cmd = " \\\n".join(cmd_lines)

        # And then to write the generated string directly to the file.
        cmd_path = config["outdir-generated"].joinpath(pkgmgr + '_cmd.txt')
        cmd_path.parent.mkdir(parents=True, exist_ok=True)
        with open(str(cmd_path), mode='w') as fout:
            fout.write(cmd)


def generate_tool_versions():
    """Generate an tool version number requirement from tool_requirements.py

    The version number per tool will be saved in outdir-generated/version_$TOOL_NAME.txt
    """

    # And then write a version file for every tool.
    for tool, req in TOOL_REQUIREMENTS.items():
        version_path = config["outdir-generated"].joinpath('version_' + tool + '.txt')
        version_path.parent.mkdir(parents=True, exist_ok=True)
        with open(str(version_path), mode='w') as fout:
            fout.write(req.min_version)


def generate_dif_docs():
    """Generate doxygen documentation and DIF listings from DIF source comments.

    This invokes Doxygen, and a few other things. Be careful of changing any
    paths here, some correspond to paths in other configuration files.
    """

    logging.info("Generating Software API Documentation (Doxygen)...")

    doxygen_out_path = config["outdir-generated"].joinpath("sw")

    # The next two paths correspond to relative paths specified in the Doxyfile
    doxygen_xml_path = doxygen_out_path.joinpath("api-xml")

    # We need to prepare this path because doxygen won't `mkdir -p`
    doxygen_sw_path = doxygen_out_path.joinpath("public-api/sw/apis")
    doxygen_sw_path.mkdir(parents=True, exist_ok=True)

    # This is where warnings will be generated
    doxygen_warnings_path = doxygen_out_path.joinpath("doxygen_warnings.log")
    if doxygen_warnings_path.exists():
        doxygen_warnings_path.unlink()

    doxygen_args = [
        "doxygen",
        str(SRCTREE_TOP.joinpath("util/doxygen/Doxyfile")),
    ]

    doxygen_results = subprocess.run(  # noqa: F841
        doxygen_args, check=True,
        cwd=str(SRCTREE_TOP), stdout=subprocess.PIPE,
        env=dict(
            os.environ,
            SRCTREE_TOP=str(SRCTREE_TOP),
            DOXYGEN_OUT=str(doxygen_out_path),
        ))

    logging.info("Generated Software API Documentation (Doxygen)")

    if doxygen_warnings_path.exists():
        logging.warning("Doxygen Generated Warnings "
                        "(saved in {})".format(str(doxygen_warnings_path)))

    combined_xml = gen_dif_listing.get_combined_xml(doxygen_xml_path)

    dif_paths = []
    dif_paths.extend(sorted(SRCTREE_TOP.joinpath(config["difs-directory"]).glob("dif_*.h")))

    dif_listings_root_path = config["outdir-generated"].joinpath("sw/difs_listings")
    difrefs_root_path = config["outdir-generated"].joinpath("sw/difref")

    for dif_header_path in dif_paths:
        dif_header = str(dif_header_path.relative_to(SRCTREE_TOP))

        dif_listings_filename = dif_listings_root_path.joinpath(dif_header + ".html")
        dif_listings_filename.parent.mkdir(parents=True, exist_ok=True)

        with open(str(dif_listings_filename), mode='w') as dif_listings_html:
            gen_dif_listing.gen_listing_html(combined_xml, dif_header,
                                             dif_listings_html)

        difref_functions = gen_dif_listing.get_difref_info(combined_xml, dif_header)
        for function in difref_functions:
            difref_filename = difrefs_root_path.joinpath(function["name"] + '.html')
            difref_filename.parent.mkdir(parents=True, exist_ok=True)

            with open(str(difref_filename), mode='w') as difref_html:
                gen_dif_listing.gen_difref_html(function, difref_html)

        logging.info("Generated DIF Listing for {}".format(dif_header))


def generate_top_docs():
    '''Generate top level documentation fragments.

    The result is in Markdown format and is written to
    outdir-generated/top_docs_directory/<top level name>/*.md.
    '''
    script = SRCTREE_TOP / 'util' / 'design' / 'gen-top-docs.py'
    outdir = config['outdir-generated'] / config["top_docs_directory"]
    for top in config["hw_top_definitions"]:
        subprocess.run([str(script), "-t", top, "-o", outdir])


def generate_otbn_isa():
    '''Generate the OTBN ISA documentation fragment

    The result is in Markdown format and is written to
    outdir-generated/otbn-isa.md

    '''
    otbn_dir = SRCTREE_TOP / 'hw/ip/otbn'
    script = otbn_dir / 'util/yaml_to_doc.py'
    yaml_file = otbn_dir / 'data/insns.yml'
    impl_file = otbn_dir / 'dv/otbnsim/sim/insn.py'

    out_dir = config['outdir-generated'].joinpath('otbn-isa')
    subprocess.run([str(script), str(yaml_file), str(impl_file), str(out_dir)],
                   check=True)


def hugo_match_version(hugo_bin_path, version):
    logging.info("Hugo binary path: %s", hugo_bin_path)
    args = [str(hugo_bin_path), "version"]
    process = subprocess.run(args,
                             universal_newlines=True,
                             stdout=subprocess.PIPE,
                             check=True,
                             cwd=str(SRCTREE_TOP))

    logging.info("Checking for correct Hugo version: %s", version)
    # Hugo version string example:
    # "Hugo Static Site Generator v0.59.0-1DD0C69C/extended linux/amd64 BuildDate: 2019-10-21T09:45:38Z"  # noqa: E501
    return bool(re.search("v" + version + ".*[/+]extended", process.stdout))


def install_hugo(install_dir):
    """Download and "install" hugo into |install_dir|

    install_dir is created if it doesn't exist yet.

    Limitations:
      Currently only 64-bit x86 Linux and macOS is supported."""

    # TODO: Support more configurations
    if platform.system() == 'Linux' and platform.machine() == 'x86_64':
        download_url = ('https://github.com/gohugoio/hugo/releases/download/v{version}'
                        '/hugo_extended_{version}_Linux-64bit.tar.gz').format(
                            version=HUGO_EXTENDED_VERSION)

    elif platform.system() == 'Darwin' and platform.machine() == 'x86_64':
        download_url = ('https://github.com/gohugoio/hugo/releases/download/v{version}'
                        '/hugo_extended_{version}_macOS-64bit.tar.gz').format(
                            version=HUGO_EXTENDED_VERSION)

    else:
        logging.fatal(
            "Auto-install of hugo only supported for 64-bit x86 Linux and "
            "macOS. Manually install hugo and re-run this script with --force-global.")
        return False

    install_dir.mkdir(exist_ok=True, parents=True)
    hugo_bin_path = install_dir / 'hugo'

    try:
        if hugo_match_version(hugo_bin_path, HUGO_EXTENDED_VERSION):
            return hugo_bin_path
    except PermissionError:
        # If there is an error checking the version just continue to download
        logging.info("Hugo version could not be verified. Continue to download.")
    except FileNotFoundError:
        pass

    # TODO: Investigate the use of Python builtins for downloading. Extracting
    # the archive will probably will be a call to tar.
    cmd = 'curl -sL {download_url} | tar -xzO hugo > {hugo_bin_file}'.format(
        hugo_bin_file=str(hugo_bin_path), download_url=download_url)
    logging.info("Calling %s to download hugo.", cmd)
    subprocess.run(cmd, shell=True, check=True, cwd=str(SRCTREE_TOP))
    hugo_bin_path.chmod(0o755)
    return hugo_bin_path


def invoke_hugo(preview, bind_wan, hugo_opts, hugo_bin_path):
    site_docs = SRCTREE_TOP.joinpath('site', 'docs')
    config_file = str(site_docs.joinpath('config.toml'))
    layout_dir = str(site_docs.joinpath('layouts'))
    args = [
        str(hugo_bin_path),
        "--config",
        config_file,
        "--destination",
        str(config["outdir"]),
        "--contentDir",
        str(SRCTREE_TOP),
        "--layoutDir",
        layout_dir,
        # This option is needed because otherwise Hugo hangs trying to follow
        # Bazel symlinks (even though they're in config.toml's ignoreFiles):
        # see https://github.com/lowRISC/opentitan/issues/12322 for details.
        "--watch=false",
    ]
    if preview:
        args += ["server"]
        # --bind-wan only applies when previewing.
        if bind_wan:
            args += ["--bind", "0.0.0.0", "--baseURL",
                     "http://" + socket.getfqdn()]
    if hugo_opts is not None:
        args += hugo_opts

    subprocess.run(args, check=True, cwd=str(SRCTREE_TOP))


def main():
    logging.basicConfig(level=logging.INFO,
                        format="%(asctime)s - %(message)s",
                        datefmt="%Y-%m-%d %H:%M")

    parser = argparse.ArgumentParser(
        prog="build_docs",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        usage=USAGE)
    parser.add_argument(
        '--preview',
        action='store_true',
        help="""Starts a local server with live reload (updates triggered upon
             changes in the documentation files). This feature is intended
             to preview the documentation locally.""")
    parser.add_argument(
        '--bind-wan',
        action='store_true',
        help="""When previewing, bind to all interfaces (instead of just
            localhost).  This makes the documentation preview visible from
            other hosts.""")
    parser.add_argument(
        '--force-global',
        action='store_true',
        help="""Use a global installation of Hugo. This skips the version
            check and relies on Hugo to be available from the environment.""")
    parser.add_argument(
        '--hugo-opts',
        nargs=argparse.REMAINDER,
        help="""Indicates that all following arguments should be passed as
            additional options to hugo.  This may be useful for controlling
            server bindings and so forth.""")
    parser.add_argument('--hugo', help="""TODO""")

    args = parser.parse_args()

    generate_hardware_blocks()
    generate_dashboards()
    generate_testplans()
    generate_selfdocs()
    generate_pkg_reqs()
    generate_tool_versions()
    generate_dif_docs()
    generate_otbn_isa()
    generate_top_docs()

    hugo_localinstall_dir = SRCTREE_TOP / 'build' / 'docs-hugo'
    os.environ["PATH"] += os.pathsep + str(hugo_localinstall_dir)

    hugo_bin_path = "hugo"
    if not args.force_global:
        try:
            hugo_bin_path = install_hugo(hugo_localinstall_dir)
        except KeyboardInterrupt:
            pass

    try:
        invoke_hugo(args.preview, args.bind_wan, args.hugo_opts, hugo_bin_path)
    except subprocess.CalledProcessError:
        sys.exit("Error building site")
    except PermissionError:
        sys.exit("Error running Hugo")
    except KeyboardInterrupt:
        pass


if __name__ == "__main__":
    main()
