#!/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 io
import logging
import os
import platform
import re
import shutil
import subprocess
import textwrap
from pathlib import Path

import hjson

import dashboard.gen_dashboard_entry as gen_dashboard_entry
import reggen.gen_cfg_html as gen_cfg_html
import reggen.gen_html as gen_html
import reggen.validate as validate
import reggen.gen_selfdoc as reggen_selfdoc
import testplanner.testplan_utils as testplan_utils
import tlgen

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

# Version of hugo extended to be used to build the docs
HUGO_EXTENDED_VERSION = "0.60.0"

# 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/top_earlgrey/ip/alert_handler/data/autogen/alert_handler.hjson",
        "hw/ip/entropy_src/data/entropy_src.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/nmi_gen/data/nmi_gen.hjson",
        "hw/ip/padctrl/data/padctrl.hjson",
        "hw/top_earlgrey/ip/pinmux/data/autogen/pinmux.hjson",
        "hw/top_earlgrey/ip/rv_plic/data/autogen/rv_plic.hjson",
        "hw/ip/rv_timer/data/rv_timer.hjson",
        "hw/ip/spi_device/data/spi_device.hjson",
        "hw/ip/uart/data/uart.hjson",
        "hw/ip/usbdev/data/usbdev.hjson",
        "hw/ip/usbuart/data/usbuart.hjson",
    ],

    # Pre-generate dashboard fragments from these directories.
    "dashboard_definitions": [
        "hw/ip",
    ],

    # Pre-generate testplan fragments from these files.
    "testplan_definitions": [
        "hw/ip/aes/data/aes_testplan.hjson",
        "hw/ip/alert_handler/data/alert_handler_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/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/uart/data/uart_testplan.hjson",
        "hw/ip/usbdev/data/usbdev_testplan.hjson",
        "hw/ip/tlul/data/tlul_testplan.hjson",
        "hw/top_earlgrey/data/standalone_sw_testplan.hjson",
        "util/testplanner/examples/foo_testplan.hjson",
    ],

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

    # 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 in config["dashboard_definitions"]:
        hjson_paths = []
        hjson_paths.extend(
            sorted(SRCTREE_TOP.joinpath(dashboard).rglob('*.prj.hjson')))

        dashboard_path = config["outdir-generated"].joinpath(
            dashboard, 'dashboard')
        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"]:
        hardware_file = open(str(SRCTREE_TOP.joinpath(hardware)))
        regs = hjson.load(hardware_file,
                          use_decimal=True,
                          object_pairs_hook=validate.checking_dict)
        if validate.validate(regs) == 0:
            logging.info("Parsed %s" % (hardware))
        else:
            logging.fatal("Failed to parse %s" % (hardware))

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

        regs_html = open(str(base_path.parent.joinpath(base_path.name +
                                                   '.registers')),
                         mode='w')
        gen_html.gen_html(regs, regs_html)
        regs_html.close()

        hwcfg_html = open(str(base_path.parent.joinpath(base_path.name + '.hwcfg')),
                          mode='w')
        gen_cfg_html.gen_cfg_html(regs, hwcfg_html)
        hwcfg_html.close()


def generate_testplans():
    for testplan in config["testplan_definitions"]:
        plan = testplan_utils.parse_testplan(SRCTREE_TOP.joinpath(testplan))

        plan_path = config["outdir-generated"].joinpath(testplan + '.testplan')
        plan_path.parent.mkdir(parents=True, exist_ok=True)

        testplan_html = open(str(plan_path), mode='w')
        testplan_utils.gen_html_testplan_table(plan, testplan_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_apt_reqs():
    """Generate an apt-get command line invocation from apt-requirements.txt

    This will be saved in outdir-generated/apt_cmd.txt
    """
    # Read the apt-requirements.txt
    apt_requirements = []
    requirements_file = open(str(SRCTREE_TOP.joinpath("apt-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
            apt_requirements.append(package)

    apt_cmd = "$ sudo apt-get install " + " ".join(apt_requirements)
    apt_cmd_lines = textwrap.wrap(apt_cmd,
                                  width=78,
                                  replace_whitespace=True,
                                  subsequent_indent='    ')
    # Newlines need to be escaped
    apt_cmd = " \\\n".join(apt_cmd_lines)

    # And then to write the generated string directly to the file.
    apt_cmd_path = config["outdir-generated"].joinpath('apt_cmd.txt')
    apt_cmd_path.parent.mkdir(parents=True, exist_ok=True)
    with open(str(apt_cmd_path), mode='w') as fout:
        fout.write(apt_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
    """

    # Populate __TOOL_REQUIREMENTS__
    requirements_file = str(SRCTREE_TOP.joinpath("tool_requirements.py"))
    exec(open(requirements_file).read(), globals())

    # And then write a version file for every tool.
    for tool in __TOOL_REQUIREMENTS__:
        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(__TOOL_REQUIREMENTS__[tool])


def is_hugo_extended():
    args = ["hugo", "version"]
    process = subprocess.run(args,
                             universal_newlines=True,
                             stdout=subprocess.PIPE,
                             check=True,
                             cwd=str(SRCTREE_TOP))

    # Hugo version string example:
    # Hugo Static Site Generator v0.59.0-1DD0C69C/extended linux/amd64 BuildDate: 2019-10-21T09:45:38Z
    return bool(re.search("v\d+\.\d+\.\d+.*/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 Linux is supported."""

    # TODO: Support more configurations
    if platform.system() != 'Linux' or platform.machine() != 'x86_64':
        logging.fatal(
            "Auto-install of hugo only supported for 64 bit Linux "
            "currently. Manually install hugo and re-run this script.")
        return False

    download_url = 'https://github.com/gohugoio/hugo/releases/download/v{version}/hugo_extended_{version}_Linux-64bit.tar.gz'.format(
        version=HUGO_EXTENDED_VERSION)

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

    # 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 --overwrite 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 True


def invoke_hugo(preview):
    site_docs = SRCTREE_TOP.joinpath('site', 'docs')
    config_file = str(site_docs.joinpath('config.toml'))
    layout_dir = str(site_docs.joinpath('layouts'))
    args = [
        "hugo",
        "--config",
        config_file,
        "--destination",
        str(config["outdir"]),
        "--contentDir",
        str(SRCTREE_TOP),
        "--layoutDir",
        layout_dir,
    ]
    if preview:
        args += ["server"]
    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('--hugo', help="""TODO""")

    args = parser.parse_args()

    generate_hardware_blocks()
    generate_dashboards()
    generate_testplans()
    generate_selfdocs()
    generate_apt_reqs()
    generate_tool_versions()

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

    try:
        if not is_hugo_extended():
            logging.info(
                "Hugo extended (with SASS support) is required, but only non-extended version found. "
                "Installing local copy and re-trying.")
            install_hugo(hugo_localinstall_dir)

        invoke_hugo(args.preview)
    except FileNotFoundError:
        logging.info("Hugo not found. Installing local copy and re-trying.")
        install_hugo(hugo_localinstall_dir)
        invoke_hugo(args.preview)
    except KeyboardInterrupt:
        pass


if __name__ == "__main__":
    main()
