#!/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.
'''Produces a representation of the dependencies between Banjo libraries.'''

import argparse
import copy
import json
import re
import sys

_LIBRARY_LABEL = r'^//sdk/banjo/([^:]+):\1(\.\.\.)?$'

_DUMMY_LIBRARIES = set([
    'zircon.hw.pci',
])


def _extract_dependencies(label, base_depth, deps, result):
    index = 0
    current_label = None
    dep_labels = []
    while index < len(deps):
        depth = deps[index].index('//')
        if depth <= base_depth:
            break
        elif depth == base_depth + 2:
            current_label = re.sub(r'\.\.\.', '', deps[index]).strip()
            dep_labels.append(current_label)
            index += 1
        else:
            index += _extract_dependencies(
                current_label, base_depth + 2, deps[index:], result)
    result[label] = dep_labels
    return index


def extract_dependencies(deps):
    result = {}
    _extract_dependencies('main', -2, deps, result)
    return result


def filter_banjo_libraries(deps):
    # This filters dep lists to retain only Banjo libraries.
    normalize_deps = lambda l: list(
        filter(lambda i: i, map(lambda c: get_library_label(c), l)))

    # Retain only Banjo libraries at the top level and normalize their dep lists.
    result = dict(
        map(
            lambda r: (r[0], normalize_deps(r[1])),
            filter(
                lambda t: t[0],
                map(lambda p: (get_library_label(p[0]), p[1]), deps.items()))))

    # Add all standalone libraries.
    for lib in normalize_deps(deps['main']):
        if lib not in result:
            result[lib] = []

    return result


def get_library_label(label):
    match = re.match(_LIBRARY_LABEL, label)
    return match.group(1) if match else None


def remove_library(name, deps):
    if name in deps:
        del deps[name]
    for v in deps.values():
        if name in v:
            v.remove(name)


def add_back_edges(deps):
    result = copy.deepcopy(deps)
    for lib, lib_deps in deps.items():
        for d in lib_deps:
            result[d].append(lib)
    return result


def find_connected_components(deps):

    def find_component(library, component):
        connections = deps.pop(library)
        component.add(library)
        for c in connections:
            if c not in deps:
                continue
            find_component(c, component)
        return component

    result = []
    while deps:
        result.append(find_component(list(deps.keys())[0], set()))
    return result


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--gn-deps',
        help='Path to the JSON-formatted files with dependency info',
        required=True)
    args = parser.parse_args()

    with open(args.gn_deps, 'r') as deps_file:
        deps = json.load(deps_file)

    all_deps = extract_dependencies(deps['//sdk/banjo:banjo']['deps'])
    banjo_deps = filter_banjo_libraries(all_deps)
    remove_library('zx', banjo_deps)
    remove_library('fuchsia.hardware.composite', banjo_deps)
    banjo_graph = add_back_edges(banjo_deps)

    components = find_connected_components(banjo_graph)

    blocked = filter(lambda g: g & _DUMMY_LIBRARIES, components)
    if blocked:
        print()
        print('Blocked by dummy libraries')
        all_blocked = set()
        for group in blocked:
            all_blocked |= group
        for library in sorted(all_blocked - _DUMMY_LIBRARIES):
            print(' - ' + library)

    standalones = filter(
        lambda s: len(s) == 1 and not s & _DUMMY_LIBRARIES, components)
    if standalones:
        print()
        print('Standalone:')
        for singleton in standalones:
            print(' - ' + next(iter(singleton)))

    groups = map(
        lambda t: t[1],
        sorted(
            map(
                lambda s: (len(s), s),
                filter(
                    lambda g: len(g) > 1 and not g & _DUMMY_LIBRARIES,
                    components))))
    if groups:
        print()
        print('Groups:')
        for index, group in enumerate(groups):
            print('[' + str(index) + ']')
            for library in sorted(group):
                print(' - ' + library)

    return 0


if __name__ == '__main__':
    sys.exit(main())
