# Copyright 2017 The Bazel Authors. All rights reserved.
#
# 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.

"""Skylib module containing common set algorithms.

CAUTION: Operating on sets, particularly sets contained in providers, may
asymptotically slow down the analysis phase. While constructing large sets with
addition/union is fast (there is no linear-time copy involved), the
`difference` function and various comparison predicates involve linear-time
traversals.

For convenience, the functions in this module can take either sets or lists as
inputs; operations that take lists treat them as if they were sets (i.e.,
duplicate elements are ignored). Functions that return new sets always return
them as the `set` type, regardless of the types of the inputs.
"""

_depset_type = type(depset())
_list_type = type([])

def _precondition_only_sets_or_lists(*args):
    """Verifies that all arguments are either sets or lists.

    The build will fail if any of the arguments is neither a set nor a list.

    Args:
      *args: A list of values that must be sets or lists.
    """
    for a in args:
        t = type(a)
        if t not in (_depset_type, _list_type):
            fail("Expected arguments to be depset or list, but found type %s: %r" %
                 (t, a))

def _depset_to_list(val):
    """Converts a depset to a list.

    If the given value is a depset, will return the list representation of
    the depset. Otherwise, will return the value itself.

    Args:
      val: The value to be optionally converted and returned.
    Returns:
      The converted value.
    """
    if type(val) == _depset_type:
        return val.to_list()
    else:
        return val

def _is_equal(a, b):
    """Returns whether two sets are equal.

    Args:
      a: A depset or a list.
      b: A depset or a list.

    Returns:
      True if `a` is equal to `b`, False otherwise.
    """
    _precondition_only_sets_or_lists(a, b)

    # Convert both values to a depset then back to a list to remove duplicates.
    a = _depset_to_list(depset(a))
    b = _depset_to_list(depset(b))
    return sorted(a) == sorted(b)

def _is_subset(a, b):
    """Returns whether `a` is a subset of `b`.

    Args:
      a: A depset or a list.
      b: A depset or a list.

    Returns:
      True if `a` is a subset of `b`, False otherwise.
    """
    _precondition_only_sets_or_lists(a, b)
    for e in _depset_to_list(a):
        if e not in _depset_to_list(b):
            return False
    return True

def _disjoint(a, b):
    """Returns whether two sets are disjoint.

    Two sets are disjoint if they have no elements in common.

    Args:
      a: A set or list.
      b: A set or list.

    Returns:
      True if `a` and `b` are disjoint, False otherwise.
    """
    _precondition_only_sets_or_lists(a, b)
    for e in _depset_to_list(a):
        if e in _depset_to_list(b):
            return False
    return True

def _intersection(a, b):
    """Returns the intersection of two sets.

    Args:
      a: A set or list.
      b: A set or list.

    Returns:
      A set containing the elements that are in both `a` and `b`.
    """
    _precondition_only_sets_or_lists(a, b)
    return depset([e for e in _depset_to_list(a) if e in _depset_to_list(b)])

def _union(*args):
    """Returns the union of several sets.

    Args:
      *args: An arbitrary number of sets or lists.

    Returns:
      The set union of all sets or lists in `*args`.
    """
    _precondition_only_sets_or_lists(*args)
    args_deps = [depset(x) if type(x) == _list_type else x for x in args]
    return depset(transitive = args_deps)

def _difference(a, b):
    """Returns the elements in `a` that are not in `b`.

    Args:
      a: A set or list.
      b: A set or list.

    Returns:
      A set containing the elements that are in `a` but not in `b`.
    """
    _precondition_only_sets_or_lists(a, b)
    return depset([e for e in _depset_to_list(a) if e not in _depset_to_list(b)])

sets = struct(
    difference = _difference,
    disjoint = _disjoint,
    intersection = _intersection,
    is_equal = _is_equal,
    is_subset = _is_subset,
    union = _union,
)
