#!/usr/bin/env python
#
# Copyright (C) 2022 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Verify that one set of hidden API flags is a subset of another."""
import dataclasses
import typing

from itertools import chain


@dataclasses.dataclass()
class Node:
    """A node in the signature trie."""

    # The type of the node.
    #
    # Leaf nodes are of type "member".
    # Interior nodes can be either "package", or "class".
    type: str

    # The selector of the node.
    #
    # That is a string that can be used to select the node, e.g. in a pattern
    # that is passed to InteriorNode.get_matching_rows().
    selector: str

    def values(self, selector):
        """Get the values from a set of selected nodes.

        :param selector: a function that can be applied to a key in the nodes
            attribute to determine whether to return its values.

        :return: A list of iterables of all the values associated with
            this node and its children.
        """
        values = []
        self.append_values(values, selector)
        return values

    def append_values(self, values, selector):
        """Append the values associated with this node and its children.

        For each item (key, child) in nodes the child node's values are returned
        if and only if the selector returns True when called on its key. A child
        node's values are all the values associated with it and all its
        descendant nodes.

        :param selector: a function that can be applied to a key in the nodes
        attribute to determine whether to return its values.
        :param values: a list of a iterables of values.
        """
        raise NotImplementedError("Please Implement this method")

    def child_nodes(self):
        """Get an iterable of the child nodes of this node."""
        raise NotImplementedError("Please Implement this method")


# pylint: disable=line-too-long
@dataclasses.dataclass()
class InteriorNode(Node):
    """An interior node in a trie.

    Each interior node has a dict that maps from an element of a signature to
    either another interior node or a leaf. Each interior node represents either
    a package, class or nested class. Class members are represented by a Leaf.

    Associating the set of flags [public-api] with the signature
    "Ljava/lang/Object;->String()Ljava/lang/String;" will cause the following
    nodes to be created:
    Node()
    ^- package:java -> Node()
       ^- package:lang -> Node()
           ^- class:Object -> Node()
              ^- member:String()Ljava/lang/String; -> Leaf([public-api])

    Associating the set of flags [blocked,core-platform-api] with the signature
    "Ljava/lang/Character$UnicodeScript;->of(I)Ljava/lang/Character$UnicodeScript;"
    will cause the following nodes to be created:
    Node()
    ^- package:java -> Node()
       ^- package:lang -> Node()
           ^- class:Character -> Node()
              ^- class:UnicodeScript -> Node()
                 ^- member:of(I)Ljava/lang/Character$UnicodeScript;
                    -> Leaf([blocked,core-platform-api])
    """

    # pylint: enable=line-too-long

    # A dict from an element of the signature to the Node/Leaf containing the
    # next element/value.
    nodes: typing.Dict[str, Node] = dataclasses.field(default_factory=dict)

    # pylint: disable=line-too-long
    @staticmethod
    def signature_to_elements(signature):
        """Split a signature or a prefix into a number of elements:

        1. The packages (excluding the leading L preceding the first package).
        2. The class names, from outermost to innermost.
        3. The member signature.
        e.g.
        Ljava/lang/Character$UnicodeScript;->of(I)Ljava/lang/Character$UnicodeScript;
        will be broken down into these elements:
        1. package:java
        2. package:lang
        3. class:Character
        4. class:UnicodeScript
        5. member:of(I)Ljava/lang/Character$UnicodeScript;
        """
        # Remove the leading L.
        #  - java/lang/Character$UnicodeScript;->of(I)Ljava/lang/Character$UnicodeScript;
        text = signature.removeprefix("L")
        # Split the signature between qualified class name and the class member
        # signature.
        #  0 - java/lang/Character$UnicodeScript
        #  1 - of(I)Ljava/lang/Character$UnicodeScript;
        parts = text.split(";->")
        # If there is no member then this will be an empty list.
        member = parts[1:]
        # Split the qualified class name into packages, and class name.
        #  0 - java
        #  1 - lang
        #  2 - Character$UnicodeScript
        elements = parts[0].split("/")
        last_element = elements[-1]
        wildcard = []
        classes = []
        if "*" in last_element:
            if last_element not in ("*", "**"):
                raise Exception(f"Invalid signature '{signature}': invalid "
                                f"wildcard '{last_element}'")
            packages = elements[0:-1]
            # Cannot specify a wildcard and target a specific member
            if member:
                raise Exception(f"Invalid signature '{signature}': contains "
                                f"wildcard '{last_element}' and "
                                f"member signature '{member[0]}'")
            wildcard = [last_element]
        else:
            packages = elements[0:-1]
            # Split the class name into outer / inner classes
            #  0 - Character
            #  1 - UnicodeScript
            classes = last_element.removesuffix(";").split("$")

        # Assemble the parts into a single list, adding prefixes to identify
        # the different parts. If a wildcard is provided then it looks something
        # like this:
        #  0 - package:java
        #  1 - package:lang
        #  2 - *
        #
        # Otherwise, it looks something like this:
        #  0 - package:java
        #  1 - package:lang
        #  2 - class:Character
        #  3 - class:UnicodeScript
        #  4 - member:of(I)Ljava/lang/Character$UnicodeScript;
        return list(
            chain([("package", x) for x in packages],
                  [("class", x) for x in classes],
                  [("member", x) for x in member],
                  [("wildcard", x) for x in wildcard]))

    # pylint: enable=line-too-long

    @staticmethod
    def split_element(element):
        element_type, element_value = element
        return element_type, element_value

    @staticmethod
    def element_type(element):
        element_type, _ = InteriorNode.split_element(element)
        return element_type

    @staticmethod
    def elements_to_selector(elements):
        """Compute a selector for a set of elements.

        A selector uniquely identifies a specific Node in the trie. It is
        essentially a prefix of a signature (without the leading L).

        e.g. a trie containing "Ljava/lang/Object;->String()Ljava/lang/String;"
        would contain nodes with the following selectors:
        * "java"
        * "java/lang"
        * "java/lang/Object"
        * "java/lang/Object;->String()Ljava/lang/String;"
        """
        signature = ""
        preceding_type = ""
        for element in elements:
            element_type, element_value = InteriorNode.split_element(element)
            separator = ""
            if element_type == "package":
                separator = "/"
            elif element_type == "class":
                if preceding_type == "class":
                    separator = "$"
                else:
                    separator = "/"
            elif element_type == "wildcard":
                separator = "/"
            elif element_type == "member":
                separator += ";->"

            if signature:
                signature += separator

            signature += element_value

            preceding_type = element_type

        return signature

    def add(self, signature, value, only_if_matches=False):
        """Associate the value with the specific signature.

        :param signature: the member signature
        :param value: the value to associated with the signature
        :param only_if_matches: True if the value is added only if the signature
             matches at least one of the existing top level packages.
        :return: n/a
        """
        # Split the signature into elements.
        elements = self.signature_to_elements(signature)
        # Find the Node associated with the deepest class.
        node = self
        for index, element in enumerate(elements[:-1]):
            if element in node.nodes:
                node = node.nodes[element]
            elif only_if_matches and index == 0:
                return
            else:
                selector = self.elements_to_selector(elements[0:index + 1])
                next_node = InteriorNode(
                    type=InteriorNode.element_type(element), selector=selector)
                node.nodes[element] = next_node
                node = next_node
        # Add a Leaf containing the value and associate it with the member
        # signature within the class.
        last_element = elements[-1]
        last_element_type = self.element_type(last_element)
        if last_element_type != "member":
            raise Exception(
                f"Invalid signature: {signature}, does not identify a "
                "specific member")
        if last_element in node.nodes:
            raise Exception(f"Duplicate signature: {signature}")
        leaf = Leaf(
            type=last_element_type,
            selector=signature,
            value=value,
        )
        node.nodes[last_element] = leaf

    def get_matching_rows(self, pattern):
        """Get the values (plural) associated with the pattern.

        e.g. If the pattern is a full signature then this will return a list
        containing the value associated with that signature.

        If the pattern is a class then this will return a list containing the
        values associated with all members of that class.

        If the pattern ends with "*" then the preceding part is treated as a
        package and this will return a list containing the values associated
        with all the members of all the classes in that package.

        If the pattern ends with "**" then the preceding part is treated
        as a package and this will return a list containing the values
        associated with all the members of all the classes in that package and
        all sub-packages.

        :param pattern: the pattern which could be a complete signature or a
        class, or package wildcard.
        :return: an iterable containing all the values associated with the
        pattern.
        """
        elements = self.signature_to_elements(pattern)
        node = self

        # Include all values from this node and all its children.
        selector = lambda x: True

        last_element = elements[-1]
        last_element_type, last_element_value = self.split_element(last_element)
        if last_element_type == "wildcard":
            elements = elements[:-1]
            if last_element_value == "*":
                # Do not include values from sub-packages.
                selector = lambda x: InteriorNode.element_type(x) != "package"

        for element in elements:
            if element in node.nodes:
                node = node.nodes[element]
            else:
                return []

        return node.values(selector)

    def append_values(self, values, selector):
        for key, node in self.nodes.items():
            if selector(key):
                node.append_values(values, lambda x: True)

    def child_nodes(self):
        return self.nodes.values()


@dataclasses.dataclass()
class Leaf(Node):
    """A leaf of the trie"""

    # The value associated with this leaf.
    value: typing.Any

    def append_values(self, values, selector):
        values.append(self.value)

    def child_nodes(self):
        return []


def signature_trie():
    return InteriorNode(type="root", selector="")
