# 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.
    """
    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,
)
