#!/usr/bin/env python3.8
# Copyright 2021 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file
"""Generate _toc.yaml for a given dart doc directory index.json.

This script takes in an index.json representing a dartdoc
directory and creates a _toc.yaml.
"""

import argparse
import collections
import json
import os
import sys
import yaml

# Dart types that can contain members.
ENCLOSING_TYPES = ["library", "class", "enum", "mixin", "extension"]
TYPE_HEADINGS = {
    "class": "Classes",
    "enum": "Enums",
    "extension": "Extensions",
    "mixin": "Mixins",
    "constant": "Constants",
    "constructor": "Constructors",
    "function": "Functions",
    "method": "Methods",
    "property": "Properties",
    "top-level constant": "Top-level Constants",
    "top-level property": "Top-level Properties",
    "typedef": "Typedefs",
}


def configure_yaml():
    # TODO: (https://fxbug.dev/83891)
    # Reevaluate whether hack described below is required moving forward.
    # yaml.dump by default sorts keys alphabetically, but most of the time we
    # need a specific order. One workaround is by passing sort_keys=False, but
    # there is another problem: Python itself prior to 3.7 does not guarantee
    # dict key order. Therefore we use collections.OrderedDict, and we set up a
    # yaml representer to emit keys & values without the
    # "!!python/object/apply:collections.OrderedDict" tag.
    def represent_dictionary_order(dumper, data):
        return dumper.represent_mapping("tag:yaml.org,2002:map", data.items())

    yaml.add_representer(collections.OrderedDict, represent_dictionary_order)


def build_toc_item(title, path=None, sub_items=None):
    """Create an item in the TOC.

    Args:
      title (str) - Title for this item.
      path (str) - Path to the page for this item.
      sub_items (list) - Items to place in a collapsible subsection.
    """
    item = collections.OrderedDict()
    item["title"] = title
    if path:
        item["path"] = path
    if sub_items:
        item["section"] = sub_items
    return item


def build_toc_content(index_file):
    """Build a TOC hierarchy from a json index produced by dart doc.

     Args:
      index_file (str) - JSON file which represents dartdoc file.
    """

    with open(index_file) as f:
        data = json.load(f)

    libraries = treeify_index(data)

    toc_items = [build_toc_item("Overview", path="/reference/dart/index.md")]
    if libraries:
        if "packageName" in libraries[0]:
            # Organize by packageName, then alphabetically
            libraries.sort(key=lambda lib: (lib["packageName"], lib["name"]))

            current_package = None
            for lib in libraries:
                # Insert a heading when we encounter a new packageName.
                if current_package != lib["packageName"]:
                    current_package = lib["packageName"]
                    toc_items.append({"heading": current_package})

                toc_items.append(element_to_toc_item(lib))

        else:
            # Older versions of Dartdoc do not provide packageName in the index.
            # TODO: (https://fxbug.dev/83893)
            # Determine if this else branch is still needed for older dartdoc versions.
            toc_items.append({"heading": "Libraries"})
            toc_items.extend(element_to_toc_item(lib) for lib in libraries)

    return {"toc": toc_items}


def treeify_index(data):
    """Convert the index data to a tree and return a list of libraries.

    Index data is a flat list where each element identifies its enclosing
    element, if applicable. Libraries are not enclosed by anything and are
    effectively the root(s) of the tree. Other elements are added to a list
    named 'members' in their enclosing element. All other data is unchanged.

    Args:
      data (list) - list of libraries with possible nested elements.
    """
    assert type(data) is list

    libraries = []
    lookup = {}
    for element in data:
        if element["type"] == "library":
            libraries.append(element)

        if element["type"] in ENCLOSING_TYPES:
            # In some cases qualifiedName is not unique so we use packageName too.
            lookup_key = "%s-%s" % (
                element["qualifiedName"], element["packageName"])
            lookup[lookup_key] = element
            element["members"] = []

        if "enclosedBy" in element:
            # enclosedBy['name'] is not specific enough for lookup (e.g. two
            # libraries could both define a class 'Foo', and if we encounter
            # something enclosed by 'Foo', we wouldn't know which is the correct
            # 'Foo'). Instead we use this element's qualifiedName up to but not
            # including the last dot-for uniqueness we also use packageName too.
            qual_name = element["qualifiedName"]
            lookup_key = "%s-%s" % (
                qual_name[:qual_name.rfind(".")], element["packageName"])
            enclosingElement = lookup[lookup_key]
            enclosingElement["members"].append(element)

    return libraries


def element_to_toc_item(element):
    """Convert an element to a TOC item, recursively converting children.

    Args:
      element (dict) - tree element represented as a dict.
    """

    sub_items = []
    if "members" in element:
        # Group members by type, then alphabetically.
        element["members"].sort(
            key=lambda member: (member["type"], member["name"]))

        current_type = None
        for member in element["members"]:
            # Insert a heading when we encounter a new type grouping.
            if current_type != member["type"]:
                current_type = member["type"]
                sub_items.append({"heading": TYPE_HEADINGS[current_type]})

            sub_items.append(element_to_toc_item(member))
    return build_toc_item(
        title=element["name"],
        path="/reference/dart/%s" % element["href"],
        sub_items=sub_items,
    )


def no_args_main(index_file, outfile):
    """Modified main function which generates a toc.yaml.

    Args:
      index_file (str) - index.json file representing generated docs
      outfile (str) - output toc.yaml file
    """
    if not os.path.isfile(index_file):
        raise RuntimeError("%s does not exist or is not a file" % index_file)

    configure_yaml()
    content = build_toc_content(index_file)
    if not content:
        raise RuntimeError("Unable to generate toc content. Build failed.")
    with open(outfile, "w") as f:
        yaml.dump(content, f, default_flow_style=False)
