# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
# SPDX-License-Identifier: Apache-2.0

'''
Process a build folder and generate a comprehensive HTML dashboard
including memory use, Kconfig values, devicetree browser, sys-init
ordering, and other general details.

Data sources
============

The following build artifacts (read from <build_dir>/zephyr/ unless noted)
are used by this script:

  <build_dir>/build_info.yml
      Build metadata produced by CMake: application source path, board
      name, west build command, and workspace top directory.

  <zephyr_base>/VERSION
      Zephyr source version (major, minor, patchlevel, extraversion).

  <build_dir>/CMakeFiles/*/CMakeCCompiler.cmake
      CMake compiler description file, parsed to extract the toolchain
      name and version string.

  zephyr/<kernel>.elf
      ELF image of the built kernel. Used by pyelftools to compute the
      memory summary (text/rodata/rwdata/bss section sizes), to check
      sys-init ordering via check_init_priorities, and by the
      scripts/footprint/size_report script to generate memory reports.

  zephyr/<kernel>.bin
      Binary image.  Only its file size is read, reported as "Bin Size"
      on the build summary page.

  zephyr/.config-trace.pickle
      Pickled output of the traceconfig script.  Contains the list of
      Kconfig symbols that were evaluated during the build, together
      with their values and source locations, used to populate the
      Kconfig browser tab.

  zephyr/edt.pickle
      Pickled edtlib.EDT object representing the fully resolved
      devicetree for the build.  Used in two ways:

      1. General devicetree browser — the full DT node tree is rendered
         as a searchable, expandable view in the Devicetree tab.

      2. Per-region memory reports — all nodes whose "compatible"
         includes "zephyr,memory-region" and whose status is "okay" are
         enumerated.  For each such node the "zephyr,memory-region"
         property provides the region name and the first "reg" entry
         provides its base address and size.  If the ELF contains at
         least one allocated section that overlaps the region's address
         range, a report is created and shown as an additional tab in the
         Memory Report view.

  zephyr/zephyr.dts
      Raw DTS source file, syntax-highlighted with Pygments and
      displayed verbatim in the Devicetree tab.
'''

import argparse
import contextlib
import glob
import html
import io
import json
import logging
import os
import pickle
import re
import shutil
import subprocess
import sys
import webbrowser
from datetime import datetime
from functools import partial
from http.server import HTTPServer, SimpleHTTPRequestHandler
from pathlib import Path

import jinja2
import yaml
from elftools.elf.constants import SH_FLAGS
from elftools.elf.elffile import ELFFile
from pygments import highlight
from pygments.formatters import HtmlFormatter  # pylint: disable=E0611
from pygments.lexers import DevicetreeLexer  # pylint: disable=E0611
from pygments.styles import get_style_by_name

sys.path.append(str(Path(__file__).parents[1] / "build"))
from check_init_priorities import Validator

sys.path.append(str(Path(__file__).parents[1] / "dts" / "python-devicetree" / "src" / "devicetree"))
from dtlib import DT

sys.path.append(str(Path(__file__).parents[1] / "footprint"))
try:
    from plot import generate_figure
    from plotly.offline.offline import get_plotlyjs
except ImportError:
    generate_figure = None

logger = logging.getLogger('dashboard')

# Online path to the kconfig browser.
KCONFIG_BROWSER = 'https://docs.zephyrproject.org/latest/kconfig.html'

# Set to match the CSS used in the HTML as it is set via CSS variable
# that we cannot access from Python script.
CSS_BS_TABLE_BG = '#f8f9fa'

# Height of the memory report plot.
MEMORY_PLOT_HEIGHT = 600

# Constants for converting from bytes to human-friendly sizes.
MEMORY_UNIT_SIZES = {
    1073741824: 'GB',
    1048576: 'MB',
    1024: 'KB',
    1: 'Bytes',
}


def display_size(byte_cnt):
    '''
    Display a number of bytes in human-readable form with a size indicator.
    '''

    if byte_cnt in [None, '']:
        return ''

    compressed_bytes = byte_cnt
    unit = 'Bytes'
    for unit_size, unit_str in MEMORY_UNIT_SIZES.items():
        if abs(byte_cnt) >= unit_size:
            compressed_bytes = float(byte_cnt) / unit_size
            unit = unit_str
            break

    return f"{compressed_bytes:.1f} {unit}".replace('.0', '')


def elf_memory_summary(elf_file):
    '''
    Get a summary of memory use from the given ELF file.

    This function will parse the given elf file and determine the total memory
    used by read-only, read-write, and executable regions.

    :param elf_file: Path to an elf file.
    :return: A dictionary with keys "bss", "rwdata", "rodata", "text", "other"
    '''

    report = {'bss': 0, 'rodata': 0, 'rwdata': 0, 'text': 0, 'other': 0}

    with ELFFile.load_from_path(elf_file) as elf:
        for section in elf.iter_sections():
            flags = section.header['sh_flags']
            size = section.header['sh_size']
            sh_type = section.header['sh_type']

            if sh_type == 'SHT_NOBITS':
                report['bss'] += size
            elif sh_type == 'SHT_PROGBITS':
                if flags & SH_FLAGS.SHF_EXECINSTR:
                    report['text'] += size
                elif flags & SH_FLAGS.SHF_WRITE:
                    report['rwdata'] += size
                elif flags & SH_FLAGS.SHF_ALLOC:
                    report['rodata'] += size
                else:
                    report['other'] += size
            else:
                report['other'] += size

    return report


class ZephyrVersion:
    '''
    Class representing the version of Zephyr kernel. See
    https://docs.zephyrproject.org/latest/project/release_process.html
    for what the fields represent.
    Data is loaded from the VERSION file in the Zephyr base.
    '''

    FIELDS = ['version_major', 'version_minor', 'patchlevel', 'version_tweak', 'extraversion']

    def __init__(self, zephyr_base):
        self.version_major = None
        self.version_minor = None
        self.patchlevel = None
        self.version_tweak = None
        self.extraversion = None

        version_file = zephyr_base / 'VERSION'

        try:
            with open(version_file, encoding='utf-8') as f:
                version_data = f.readlines()
        except OSError as e:
            logger.error(f"Unable to read version information from {version_file}: {e}")
            return

        for version_line in version_data:
            field, value = version_line.split('=')
            field = field.strip().lower()
            value = value.strip()
            if field in ZephyrVersion.FIELDS:
                setattr(self, field, value)

    def __str__(self):
        version = f"{self.version_major}.{self.version_minor}"
        if self.patchlevel and self.patchlevel != '0':
            version += f'.{self.patchlevel}'
        if self.extraversion and self.extraversion != '0':
            version += f'-{self.extraversion}'
        if self.version_tweak and self.version_tweak != '0':
            version += f'+{self.version_tweak}'
        return version


class ZephyrToolchain:
    '''
    Container for the Zephyr toolchain information.
    Extracted from the CMakeCCompiler.cmake file.
    '''

    def __init__(self, build_path):
        self.cmake_c_compiler_id = None
        self.cmake_c_compiler_version = None

        cmake_glob = build_path / 'CMakeFiles' / '*' / 'CMakeCCompiler.cmake'
        cmake_file = glob.glob(str(cmake_glob))
        if cmake_file:
            cmake_file = cmake_file[0]
        else:
            return

        try:
            with open(cmake_file, encoding='utf-8') as f:
                lines = f.readlines()
        except OSError as e:
            logger.error(f"Unable to load CMakeCCompiler.cmake file {cmake_file}: {e}")
            return

        cmake_c_compiler_id_re = re.compile(r'\s*set\(CMAKE_C_COMPILER_ID\s+"(.*)"\)')
        cmake_c_compiler_version_re = re.compile(r'\s*set\(CMAKE_C_COMPILER_VERSION\s+"(.*)"\)')

        for line in lines:
            if match := cmake_c_compiler_id_re.match(line):
                self.cmake_c_compiler_id = match.group(1)
            if match := cmake_c_compiler_version_re.match(line):
                self.cmake_c_compiler_version = match.group(1)
            if self.cmake_c_compiler_id and self.cmake_c_compiler_version:
                break

    def __str__(self):
        return f"{self.cmake_c_compiler_id} {self.cmake_c_compiler_version}"


class KconfigSymbol:
    '''
    Class representing a KconfigSymbol and its value in a given build.
    '''

    def __init__(self, name, visible, sym_type, value, src, loc, build):
        self.sym_type = sym_type
        self.visible = bool(visible == 'y')
        self.name = name
        self.value = value
        if sym_type == "string" and self.value is not None:
            self.value = f'"{self.value}"'
        self.src = src
        self.loc = loc
        self.build = build

    def loc_html(self):
        '''
        Return an HTML representation of the symbol location.
        '''
        if self.loc and self.src in ['default', 'assign']:
            fn = os.path.relpath(self.loc[0], self.build.zephyr_base)
            disp_fn = os.path.normpath(fn).replace("../", "")
            sym_loc = f'{disp_fn}:{self.loc[1]}'
        elif self.loc and self.src in ['select', 'imply']:
            if len(self.loc) > 1:
                sym_loc = " || ".join(f"({html.escape(loc)})" for loc in self.loc)
            else:
                sym_loc = html.escape(self.loc[0])
            sym_loc = f"<code>{sym_loc}</code>"
        elif self.loc is None and self.src == "default":
            sym_loc = "<i>(implicit)</i>"
        else:
            sym_loc = ''
        return sym_loc

    def src_html(self):
        '''
        Return an HTML representation of the symbol source tag.
        '''
        if self.src == "unset":
            return ''
        if self.src == "default":
            return '<span class="badge bg-secondary">default</span>'
        if self.src == "assign":
            return '<span class="badge bg-primary">assigned</span>'
        if self.src == "select":
            return '<span class="badge bg-info">selected</span>'
        if self.src == "imply":
            return '<span class="badge bg-warning">implied</span>'
        return self.src


def _build_memory_report_tree(report):
    '''
    Convert a size_report JSON dict into the tree structure expected by the
    JS tree widget.

    Returns a dict with keys "size" (total bytes) and "tree" (list of nodes).
    Each node has "expanded", "data" (name/size/displaySize/memoryType), and
    optionally "children".
    '''

    def create_node(symbol, expanded=False):
        size = symbol['size']
        return (
            {
                "expanded": expanded,
                "data": {
                    "name": symbol['name'],
                    "size": size,
                    "displaySize": display_size(size),
                    "memoryType": [loc.upper() for loc in symbol.get('loc', [])],
                },
            }
            if size
            else None
        )

    def add_children(node, children):
        if not children:
            return
        node['children'] = []
        for symbol in sorted(children, key=lambda c: c['name']):
            child_node = create_node(symbol)
            if not child_node:
                continue
            node['children'].append(child_node)
            add_children(child_node, symbol.get('children'))

    tree = {}
    symbol = report.get('symbols')
    if symbol:
        tree['size'] = symbol['size']
        tree['tree'] = []
        node = create_node(symbol, expanded=True)
        tree['tree'].append(node)
        add_children(node, symbol.get('children'))
    return tree


class ZephyrDashboard:
    '''
    Class for collecting and processing Zephyr build artifacts to create the
    HTML dashboard.
    '''

    def __init__(
        self,
        zephyr_base,
        build_path,
        output_path,
        kernel_bin_name="zephyr",
        skip_memory_report=False,
    ):
        self.zephyr_base = Path(zephyr_base)
        self.kernel_bin_name = kernel_bin_name
        self.build_path = Path(build_path) if build_path else self.zephyr_base / "build"
        self.output_path = Path(output_path) if output_path else self.build_path / "dashboard"

        self.elf_file = self.build_path / "zephyr" / f"{self.kernel_bin_name}.elf"
        self.dts_file = self.build_path / "zephyr" / "zephyr.dts"
        self.kconfig_file = self.build_path / "zephyr" / ".config"

        # Read details from the build_info.yml file.
        with open(self.build_path / "build_info.yml", encoding='utf-8') as fd:
            self.build_info = yaml.safe_load(fd)
        try:
            self.application = self.build_info['cmake']['application']['source-dir']
            base_prefix = '^' + str(self.zephyr_base.absolute()).replace('\\', '/') + '/'
            self.application = re.sub(base_prefix, '', self.application)
        except KeyError:
            self.application = None
        try:
            self.board = self.build_info['cmake']['board']['name']
        except KeyError:
            self.board = None
        try:
            self.command = self.build_info['west']['command']
            self.command = re.sub(r'\S*west', 'west', self.command)
        except KeyError:
            self.command = None
        try:
            self.topdir = Path(self.build_info['west']['topdir'])
        except KeyError:
            self.topdir = self.zephyr_base

        # Get some details on the build binary file - may not exist in all
        # builds (like QEMU).
        try:
            bin_file = self.build_path / "zephyr" / f"{self.kernel_bin_name}.bin"
            bin_stats = bin_file.stat()
            self.bin_size_str = display_size(bin_stats.st_size)
        except OSError:
            self.bin_size_str = None

        # Get some details on the build ELF file.
        elf_stats = self.elf_file.stat()
        self.elf_date_str = datetime.fromtimestamp(elf_stats.st_mtime).strftime("%Y-%m-%d %H:%M:%S")
        self.elf_size_str = display_size(elf_stats.st_size)

        self.toolchain = ZephyrToolchain(self.build_path)
        self.zephyr_version = ZephyrVersion(self.zephyr_base)

        self._init_kconfigs()
        self._init_sysinit()

        self.memory_summary = elf_memory_summary(self.elf_file)

        # Create the memory reports if they are stale.
        self.skip_memory_report = skip_memory_report
        self.memory_regions = []
        if not self.skip_memory_report:
            memory_report = self.output_path / "all_report.json"
            if not os.path.isfile(memory_report) or os.path.getmtime(
                memory_report
            ) < os.path.getmtime(self.elf_file):
                self._create_memory_reports()

    def _init_sysinit(self):
        '''
        Get the sys-init levels and validate against DT dependencies.
        '''
        validator_log = io.StringIO()
        stream_handler = logging.StreamHandler(validator_log)
        stream_handler.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))

        validator_logger = logging.getLogger('check_init_priorities')
        validator_logger.propagate = False
        validator_logger.addHandler(stream_handler)
        validator_logger.setLevel(logging.WARNING)

        with open(self.elf_file, 'rb') as fd:
            validator = Validator(self.elf_file, 'edt.pickle', validator_logger, fd)
            validator.check_edt()

        self.sys_init_errors = validator_log.getvalue().splitlines()
        self.sys_init_levels = validator.initlevels

    def _init_kconfigs(self):
        '''
        Load the kconfig trace information from the pickled data file and convert
        to a list of KconfigSymbol objects.
        '''
        pickle_path = self.build_path / "zephyr" / ".config-trace.pickle"
        with open(pickle_path, 'rb') as f:
            trace_data = pickle.load(f)
        self.kconfigs = [KconfigSymbol(*sym, build=self) for sym in trace_data]
        self.kconfigs.sort(key=lambda kc: kc.name)

    def _get_dt_memory_regions(self):
        '''
        Return a list of DT memory regions from edt.pickle.

        Each entry is a dict with "name" (str), "addr" (int), "size" (int).
        Only nodes with compatible "zephyr,memory-region", status "okay", a
        valid "zephyr,memory-region" name property, and at least one reg are
        included.
        '''
        edt_pickle_path = self.build_path / "zephyr" / "edt.pickle"
        with open(edt_pickle_path, "rb") as f:
            edt = pickle.load(f)

        regions = []
        for node in edt.compat2nodes.get("zephyr,memory-region", []):
            if node.status != "okay":
                continue
            name_prop = node.props.get("zephyr,memory-region")
            if not name_prop:
                continue
            name = name_prop.val
            if not node.regs:
                continue
            reg = node.regs[0]
            if reg.addr is None or reg.size is None:
                continue
            regions.append({"name": name, "addr": reg.addr, "size": reg.size, "path": node.path})
        return regions

    def _has_sections_in_range(self, addr, size):
        '''
        Return True if the ELF contains any allocated, non-empty section
        whose address range overlaps [addr, addr+size).
        '''
        end = addr + size
        with ELFFile.load_from_path(self.elf_file) as elf:
            for section in elf.iter_sections():
                if section["sh_size"] == 0:
                    continue
                if section["sh_flags"] & SH_FLAGS.SHF_ALLOC == 0:
                    continue
                sec_start = section["sh_addr"]
                sec_end = sec_start + section["sh_size"]
                if sec_start < end and sec_end > addr:
                    return True
        return False

    def _create_memory_reports(self):
        '''
        Use the footprint size_report tool to create the ram/rom/all JSON data.
        '''
        logger.info("Creating memory reports (may take a few minutes).")

        # Create the output location for the report files.
        self.output_path.mkdir(parents=True, exist_ok=True)

        cmd = [
            sys.executable,
            str(self.zephyr_base / "scripts" / "footprint" / "size_report"),
            '-k',
            str(self.elf_file),
            '-z',
            str(self.zephyr_base.absolute()),
            f'--workspace={self.topdir}',
            '--json',
            str(self.output_path / '{target}_report.json'),
            '--quiet',
            '--output',
            '.',
            'rom',
            'ram',
            'all',
        ]

        logger.debug(' '.join(cmd))
        try:
            subprocess.check_call(cmd)
        except subprocess.CalledProcessError as e:
            logger.error(
                f"Failed generating memory size report (exit code {e.returncode}). "
                + f"Command:\n{' '.join(e.cmd)}"
            )

        # Generate per-region reports for non-empty DT memory regions.
        try:
            regions = self._get_dt_memory_regions()
        except Exception as e:
            logger.warning(f"Could not load DT memory regions: {e}")
            regions = []

        for region in regions:
            if not self._has_sections_in_range(region["addr"], region["size"]):
                continue

            region_cmd = [
                sys.executable,
                str(self.zephyr_base / "scripts" / "footprint" / "size_report"),
                '-k',
                str(self.elf_file),
                '-z',
                str(self.zephyr_base.absolute()),
                f'--workspace={self.topdir}',
                '--json',
                str(self.output_path / f"{region['name']}_report.json"),
                '--filter-address-range',
                str(region["addr"]),
                str(region["size"]),
                '--quiet',
                '--output',
                '.',
                'all',
            ]
            logger.debug(' '.join(region_cmd))
            try:
                subprocess.check_call(region_cmd)
                self.memory_regions.append(region)
            except subprocess.CalledProcessError as e:
                logger.error(
                    f"Failed generating memory region report for {region['name']} "
                    f"(exit code {e.returncode}). Command:\n{' '.join(e.cmd)}"
                )

    def _load_memory_report(self, mem_type):
        '''
        Load the memory report of the given type from an existing json file.

        :param type: Which report, "ram", "rom", or "all"
        :return: Dictionary of the loaded memory report.
        '''
        fname = self.output_path / f"{mem_type}_report.json"
        if not os.path.isfile(fname):
            logger.error(f'Memory report file "{fname}" not found.')
            return None

        with open(fname, encoding="utf-8") as fd:
            return json.load(fd)

    def _symbols_by_size(self, report, limit=None):
        '''
        Sort the symbols from a memory report by their size.

        :param report: A memory report as created by the Zephyr size_report script.
        :param limit: How many results to return.

        :return: A list of all the symbols with the largest first.
        '''

        if not report:
            return []

        symbol_list = []

        def flatten(symbols, lst):
            for symbol in symbols:
                children = symbol.get('children')
                if children:
                    flatten(children, lst)
                elif symbol['name'][0] != '(':
                    lst.append(symbol)

        flatten(report['symbols']['children'], symbol_list)

        symbol_list = sorted(symbol_list, key=lambda s: s['size'], reverse=True)

        if limit:
            symbol_list = symbol_list[0:limit]

        return symbol_list

    def _memory_report_template_context(self, mem_type, ctxt):
        '''
        Add the HTML template context for the memory report of the given type.
        '''

        report = self._load_memory_report(mem_type)

        if report:
            tree = _build_memory_report_tree(report)
            ctxt[f'{mem_type}_report'] = json.dumps(tree)
            ctxt[f'{mem_type}_report_size'] = tree['size']

            if generate_figure:
                figure = generate_figure(report)
                figure.update_layout(paper_bgcolor=CSS_BS_TABLE_BG, height=MEMORY_PLOT_HEIGHT)
                ctxt[f'{mem_type}_plot'] = figure.to_html(full_html=False, include_plotlyjs=False)
            else:
                ctxt[f'{mem_type}_plot'] = None
        else:
            ctxt[f'{mem_type}_report'] = None
            ctxt[f'{mem_type}_plot'] = None

        if mem_type == 'all':
            ctxt['top_ten'] = self._symbols_by_size(report, 10)

    def _region_reports_template_context(self, ctxt):
        '''
        Add the HTML template context for per-region memory reports.

        Populates ctxt["memory_regions"] with a list of dicts, one per
        non-empty DT memory region, each containing:
          name       - region name (e.g. "ITCM")
          tab_id     - sanitized lowercase id safe for use in HTML attributes
          report     - JSON-encoded tree data for the JS tree widget
          report_size - total size in bytes (for percentage display)
        '''

        region_ctxt_list = []
        for region in self.memory_regions:
            name = region['name']
            tab_id = re.sub(r'[^a-zA-Z0-9]', '_', name).lower()
            fname = self.output_path / f"{name}_report.json"
            if not os.path.isfile(fname):
                logger.warning(f'Region report file "{fname}" not found.')
                continue
            with open(fname, encoding="utf-8") as fd:
                report = json.load(fd)
            if not report:
                continue
            tree = _build_memory_report_tree(report)
            if generate_figure:
                # When doing a memory-region report, the total size of the children
                # may exceed the region size by a few bytes due to how the linker
                # deals with alignment padding at a section boundary. plotly
                # barfs if they do not match, so force them to be the same.
                saved_size = report['symbols']['size']
                report['symbols']['size'] = sum(
                    node['size'] for node in report['symbols']['children']
                )
                figure = generate_figure(report)
                figure.update_layout(paper_bgcolor=CSS_BS_TABLE_BG, height=MEMORY_PLOT_HEIGHT)
                plot = figure.to_html(full_html=False, include_plotlyjs=False)
                report['symbols']['size'] = saved_size
            else:
                plot = None
            region_ctxt_list.append(
                {
                    'name': name,
                    'tab_id': tab_id,
                    'path': region['path'],
                    'region_size': region['size'],
                    'report': json.dumps(tree),
                    'report_size': tree.get('size', 0),
                    'plot': plot,
                }
            )

        ctxt['memory_regions'] = region_ctxt_list

    def _safe_relpath(self, filename):
        '''
        Returns a relative path to the file from the top dir, or
        the absolute path if a relative path cannot be established
        (on Windows with files in different drives, for example).
        '''
        try:
            return os.path.relpath(filename, start=self.topdir)
        except ValueError:
            return filename

    def _edt_fancytree(self):
        '''
        Create the Fancytree data object for the EDT tree.
        '''

        edt_pickle_path = self.build_path / "zephyr" / 'edt.pickle'
        with open(edt_pickle_path, "rb") as f:
            edt = pickle.load(f)

        # Load the same DTS file into a dtlib object so we can iterate over
        # all properties (not just ones that edtlib tracks).
        dt = DT(edt.dts_path, base_dir=self.topdir)

        label2path = {}

        def create_tree_node(dt_node, expanded=False):
            edt_node = edt.get_node(dt_node.path)
            if edt_node and edt_node.binding_path:
                binding_path = self._safe_relpath(edt_node.binding_path)
            else:
                binding_path = ""

            return {
                "id": dt_node.path,
                "expanded": expanded,
                "edtNode": {
                    "isProperty": False,
                    "name": dt_node.name,
                    "labels": dt_node.labels,
                    "filename": self._safe_relpath(dt_node.filename),
                    "lineno": dt_node.lineno,
                    "description": edt_node.description if edt_node else "",
                    "bindingPath": binding_path,
                },
            }

        def create_prop_tree_node(dt_prop, edt_prop):
            # Extract the original text value from the string conversion of the
            # property. No other way to get it from this object. Also remove
            # the trailing semi-colon and extra spaces around <>.
            value = re.sub('^.*= ', '', str(dt_prop))[:-1].replace('< ', '<').replace(' >', '>')

            # Find all the label references and create a look-up table to the node path.
            # This will be used on the render side to create links.
            for m in re.finditer(r'&(\w+)', value):
                try:
                    label2path[m.group(1)] = dt.label2node[m.group(1)].path
                except KeyError:
                    continue

            return {
                "id": dt_prop.node.path + f':{dt_prop.name}',
                "edtNode": {
                    "isProperty": True,
                    "name": dt_prop.name,
                    "value": value,
                    "filename": self._safe_relpath(dt_prop.filename),
                    "lineno": dt_prop.lineno,
                    "description": edt_prop.description if edt_prop else "",
                    "typeSpec": edt_prop.type if edt_prop else "",
                    "bindingPath": "",
                },
            }

        def add_children(tree_node, parent):
            tree_node['children'] = []

            edt_node = edt.get_node(parent.path)

            for name, dt_prop in parent.props.items():
                prop_node = create_prop_tree_node(dt_prop, edt_node.props.get(name))
                tree_node['children'].append(prop_node)

            for _, dt_node in parent.nodes.items():
                child_tree_node = create_tree_node(dt_node)
                tree_node['children'].append(child_tree_node)
                add_children(child_tree_node, dt_node)

        tree = {'tree': [], 'label2path': label2path}
        tree_node = create_tree_node(dt.root, expanded=True)
        tree['tree'].append(tree_node)
        add_children(tree_node, dt.root)

        return tree

    def create_html(self):
        '''
        Generate all the HTML output.
        '''

        templates_path = Path(__file__).parents[0] / "templates"
        template_loader = jinja2.FileSystemLoader(searchpath=str(templates_path))
        env = jinja2.Environment(
            loader=template_loader, autoescape=True, trim_blocks=True, lstrip_blocks=True
        )
        env.filters['display_size'] = display_size

        # Create the output directory tree.
        self.output_path.mkdir(parents=True, exist_ok=True)

        # Copy the static tree from the dashboard location as well as
        # doc/_static for the logo images.
        rpt_static = self.output_path / "static"
        doc_static = self.zephyr_base / "doc" / "_static"
        shutil.copytree(Path(__file__).parent.resolve() / 'static', rpt_static, dirs_exist_ok=True)
        img_dir = rpt_static / "img"
        img_dir.mkdir(exist_ok=True)
        shutil.copy2(doc_static / "images" / "logo.svg", rpt_static / "img")
        shutil.copy2(doc_static / "images" / "favicon.png", rpt_static / "img")
        shutil.copy2(doc_static / "css" / "light.css", rpt_static / "css")

        # Create the pygments CSS file.
        pygments_style = get_style_by_name('default')
        pygments_formatter = HtmlFormatter(style=pygments_style)
        pygments_css = pygments_formatter.get_style_defs('.highlight')
        with open(rpt_static / "css" / "pygments.css", 'w', encoding="utf-8") as fd:
            fd.write(pygments_css)

        # Create the plotly.js file if plotly was found.
        if generate_figure:
            with open(rpt_static / "js" / "plotly.js", 'w', encoding="utf-8") as fd:
                fd.write(get_plotlyjs())

        # ---------------------------------
        # HTML: index.html
        # ---------------------------------

        template = env.get_template("index.html")
        context = {'build': self, 'title': 'Build Summary', 'current': 'home'}
        fname = self.output_path / "index.html"
        logger.info(f"Creating {fname}")
        with open(fname, 'w', encoding="utf-8") as fd:
            fd.write(template.render(**context))

        # ---------------------------------
        # HTML: kconfig.html
        # ---------------------------------

        template = env.get_template("kconfig.html")
        context = {
            'build': self,
            'title': 'Kconfig',
            'current': 'kconfig',
            'kconfig_browser': KCONFIG_BROWSER,
        }
        fname = os.path.join(self.output_path, 'kconfig.html')
        logger.debug(f"Creating {fname}")
        with open(fname, 'w', encoding="utf-8") as fd:
            fd.write(template.render(**context))

        # ---------------------------------
        # HTML: sysinit.html
        # ---------------------------------

        template = env.get_template("sysinit.html")
        context = {'build': self, 'title': 'Sys Init', 'current': 'sysinit'}
        fname = os.path.join(self.output_path, 'sysinit.html')
        logger.debug(f"Creating {fname}")
        with open(fname, 'w', encoding="utf-8") as fd:
            fd.write(template.render(**context))

        # ---------------------------------
        # HTML: dts.html
        # ---------------------------------

        try:
            with open(self.dts_file, encoding="utf-8") as fd:
                dts_contents = fd.read()
        except OSError as e:
            logger.warning(f'Unable to load device tree file at {self.dts_file}: {e}')
            dts_contents = None

        if dts_contents:
            dts_contents = highlight(dts_contents, DevicetreeLexer(), pygments_formatter)

        edt_tree = self._edt_fancytree()

        template = env.get_template("dts.html")
        context = {
            'build': self,
            'title': 'Device Tree',
            'current': 'dts',
            'file_contents': dts_contents,
            'file_path': self.dts_file.absolute(),
            'edt_tree': json.dumps(edt_tree),
        }
        fname = self.output_path / "dts.html"
        logger.debug(f"Creating {fname}")
        with open(fname, 'w', encoding='utf-8') as fd:
            fd.write(template.render(**context))

        # ---------------------------------
        # HTML: memoryreport.html
        # ---------------------------------

        if not self.skip_memory_report:
            template = env.get_template("memoryreport.html")
            context = {
                'build': self,
                'title': 'Memory Report',
                'current': 'memory',
                'include_plotly_js': bool(generate_figure),
            }
            self._memory_report_template_context('all', context)
            self._memory_report_template_context('ram', context)
            self._memory_report_template_context('rom', context)
            self._region_reports_template_context(context)
            fname = self.output_path / 'memoryreport.html'
            logger.debug(f"Creating {fname}")
            with open(fname, 'w', encoding="utf-8") as fd:
                fd.write(template.render(**context))

        # ---------------------------------
        # HTML: elfstats.html
        # ---------------------------------

        fname = self.build_path / "zephyr" / f"{self.kernel_bin_name}.stat"
        try:
            with open(fname, encoding="utf-8") as fd:
                file_contents = fd.read()
        except OSError as e:
            logger.warning(f'Unable to load zephyr elf stat file at {fname}: {e}')
            file_contents = ''

        template = env.get_template("textviewer.html")
        context = {
            'build': self,
            'title': 'ELF Stats',
            'current': 'elfstats',
            'file_contents': file_contents,
            'file_path': fname.absolute(),
        }
        fname = self.output_path / "elfstats.html"
        logger.debug(f"Creating {fname}")
        with open(fname, 'w', encoding='utf-8') as fd:
            fd.write(template.render(**context))

    def clean_up(self):
        '''
        Clean-up any temporary files.
        '''
        for mem_type in ['ram', 'rom', 'all']:
            fname = self.output_path / f"{mem_type}_report.json"
            fname.unlink(missing_ok=True)
        for region in self.memory_regions:
            fname = self.output_path / f"{region['name']}_report.json"
            fname.unlink(missing_ok=True)

    def open_browser(self):
        '''
        Open the default web browser to the index page of the dashboard.

        Uses a one-shot HTTP server so that the browser loads from
        http://localhost, which works reliably across most platforms.
        '''

        handler = partial(SimpleHTTPRequestHandler, directory=str(self.output_path))
        server = HTTPServer(("127.0.0.1", 0), handler)
        url = f"http://127.0.0.1:{server.server_port}/index.html"
        logger.info("Serving dashboard at %s (Ctrl+C to stop)", url)
        webbrowser.open(url)
        with contextlib.suppress(KeyboardInterrupt):
            server.serve_forever()


def parse_args():
    """
    Parse command line arguments.
    """

    parser = argparse.ArgumentParser(allow_abbrev=False)

    parser.add_argument("build", help="Build directory", nargs='?', default="build")
    parser.add_argument("--output", help="Output directory for index.html")
    parser.add_argument("--zephyr-base", default=".", help="Zephyr base directory")
    parser.add_argument("--kernel-bin-name", default="zephyr", help="Kernel binary name")
    parser.add_argument(
        "--skip-memory-report",
        action="store_true",
        help="Skip the memory report to generate faster",
    )
    parser.add_argument(
        "--no-clean", action="store_true", help="Do not remove temporary memory map json data"
    )
    parser.add_argument(
        "-v", "--verbose", action="store_true", help="Print extra debugging information"
    )
    parser.add_argument("-q", "--quiet", action="store_true", help="Print nothing to the console.")
    parser.add_argument(
        "--open", action="store_true", help="Open the default web browser to the dashboard."
    )
    return parser.parse_args()


def main():
    '''
    Main function when invoked from the command-line.
    '''

    args = parse_args()

    if args.verbose:
        logging.basicConfig(level=logging.DEBUG)
        logger.setLevel(logging.DEBUG)
    elif not args.quiet:
        logging.basicConfig(level=logging.INFO)
        logger.setLevel(logging.INFO)

    output_path = args.output
    zephyr_base = args.zephyr_base
    build_path = args.build

    build = ZephyrDashboard(
        zephyr_base,
        build_path,
        output_path,
        kernel_bin_name=args.kernel_bin_name,
        skip_memory_report=args.skip_memory_report,
    )
    build.create_html()

    if not args.no_clean:
        build.clean_up()

    if args.open:
        build.open_browser()


if __name__ == "__main__":
    main()
