#!/usr/bin/env fuchsia-vendored-python
# 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.
"""
Example usage:
$ fx set ...
$ scripts/gn/gen_visibility_globs.py \
     --all="//build/config/rust/lints:deny_unused_results" \
     --allow="//build/config/rust/lints:allow_unused_results"

The output is useful for instance if you have a visibility allowlist that you want to maintain with
shortened glob paths.

To run this script's self-tests:
$ TEST=1 scripts/gn/gen_visibility_globs.py
"""

import argparse
import os
import sys
import unittest

import gn_util


def main():
    parser = argparse.ArgumentParser(
        description="Prints a visibility list for gn configs"
    )
    parser.add_argument(
        "--all",
        help="gn target that produces a universe of labels to consider",
        required=True,
    )
    parser.add_argument(
        "--allow",
        help="gn target whose current users we want to produce an allowlist for",
        required=True,
    )
    parser.add_argument(
        "--verbose",
        action=argparse.BooleanOptionalAction,
        default=False,
        help="Print progress and stats",
    )
    parser.add_argument(
        "--ignore-suffix",
        help="comma-separated list of label suffixes to ignore",
        default="",
    )

    def verbose(*vargs, **kwargs):
        if args.verbose:
            print(*vargs, **kwargs)

    args = parser.parse_args()
    verbose("Getting all labels list...")
    all_labels = gn_util.gn_refs(args.all)
    verbose(f"Found {len(all_labels)} elements in universe.")
    ignore_suffix = args.ignore_suffix.split(",")
    all_labels = (
        label
        for label in all_labels
        if not any(label.endswith(suffix) for suffix in ignore_suffix)
    )
    allow_labels = gn_util.gn_refs(args.allow)
    verbose(f"Found {len(allow_labels)} elements to allow.")
    tree = Node("/")
    update_tree(tree, all_labels, False)
    update_tree(tree, allow_labels, True)
    for path, include in tree.glob_collect():
        path = "/".join(path)
        if include:
            print(f'"{path}",')
        else:
            verbose(f"ignored {path}")

    return 0


class Node:
    def __init__(self, name, value=None):
        self.name = name
        self.children = []
        self.children = dict()
        self.value = value

    def ensure_child(self, name):
        if name not in self.children:
            self.children[name] = Node(name)
        return self.children[name]

    def visit(self, path=None):
        if path is None:
            path = []
        p = path + [self.name]
        if len(self.children) == 0:
            yield p
        for k, c in self.children.items():
            for d in c.visit(p):
                yield d

    def glob_collect(self, path=None):
        if path is None:
            path = []
        p = path + [self.name]
        if len(self.children) == 0:
            yield p, self.value
            return
        child_items = []
        can_glob = True
        for k, c in self.children.items():
            for v, include in c.glob_collect(p):
                child_items.append((v, include))
                can_glob = can_glob and include
        if can_glob:
            yield p + ["*"], True
        else:
            for v, i in child_items:
                yield v, i


def get_label_parts(label):
    """returns the parts of an absolute label as a list"""
    return label[2:].replace(":", "/").split("/")


def update_tree(tree, labels, value):
    """updates the tree for all the labels in `labels` to assume `value`."""
    for l in labels:
        parts = get_label_parts(l)
        n = tree
        for part in parts:
            n = n.ensure_child(part)
        n.value = value


class Test(unittest.TestCase):
    def test_label_parts(self):
        self.assertEqual(
            get_label_parts("//foo/bar:baz"), ["foo", "bar", "baz"]
        )

    def test_build_tree(self):
        tree = Node("/")
        update_tree(tree, ["//foo/bar:baz", "//foo/bar:bar"], False)
        bar = tree.children["foo"].children["bar"]
        self.assertIsNone(bar.value)
        self.assertFalse(bar.children["bar"].value)
        self.assertFalse(bar.children["baz"].value)
        items = []
        for x in tree.visit():
            items.append("/".join(x))
        items.sort()
        self.assertEqual(items, ["//foo/bar/bar", "//foo/bar/baz"])

        update_tree(tree, ["//foo/bar:baz"], True)
        self.assertFalse(bar.children["bar"].value)
        self.assertTrue(bar.children["baz"].value)

    def test_glob_collect(self):
        tree = Node("/")
        update_tree(
            tree,
            ["//foo/bar:baz", "//foo/bar:bar", "//foo/apple:banana"],
            False,
        )
        update_tree(tree, ["//foo/bar:baz", "//foo/bar:bar"], True)
        accepted = []
        denied = []
        for i, inc in tree.glob_collect():
            p = "/".join(i)
            if inc:
                accepted.append(p)
            else:
                denied.append(p)
        self.assertEqual(accepted, ["//foo/bar/*"])
        self.assertEqual(denied, ["//foo/apple/banana"])


if __name__ == "__main__":
    if os.getenv("TEST") is not None:
        unittest.main()
    else:
        sys.exit(main())
