# Copyright 2018 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 hash-set algorithms.

  An empty set can be created using: `sets.make()`, or it can be created with some starting values
  if you pass it an sequence: `sets.make([1, 2, 3])`. This returns a struct containing all of the
  values as keys in a dictionary - this means that all passed in values must be hashable.  The
  values in the set can be retrieved using `sets.to_list(my_set)`.
"""

load(":dicts.bzl", "dicts")

def _make(elements = None):
    """Creates a new set.

    All elements must be hashable.

    Args:
      elements: Optional sequence to construct the set out of.

    Returns:
      A set containing the passed in values.
    """
    elements = elements if elements else []
    return struct(_values = {e: None for e in elements})

def _copy(s):
    """Creates a new set from another set.

    Args:
      s: A set, as returned by `sets.make()`.

    Returns:
      A new set containing the same elements as `s`.
    """
    return struct(_values = dict(s._values))

def _to_list(s):
    """Creates a list from the values in the set.

    Args:
      s: A set, as returned by `sets.make()`.

    Returns:
      A list of values inserted into the set.
    """
    return s._values.keys()

def _insert(s, e):
    """Inserts an element into the set.

    Element must be hashable.  This mutates the orginal set.

    Args:
      s: A set, as returned by `sets.make()`.
      e: The element to be inserted.

    Returns:
       The set `s` with `e` included.
    """
    s._values[e] = None
    return s

def _remove(s, e):
    """Removes an element from the set.

    Element must be hashable.  This mutates the orginal set.

    Args:
      s: A set, as returned by `sets.make()`.
      e: The element to be removed.

    Returns:
       The set `s` with `e` removed.
    """
    s._values.pop(e)
    return s

def _contains(a, e):
    """Checks for the existence of an element in a set.

    Args:
      a: A set, as returned by `sets.make()`.
      e: The element to look for.

    Returns:
      True if the element exists in the set, False if the element does not.
    """
    return e in a._values

def _get_shorter_and_longer(a, b):
    """Returns two sets in the order of shortest and longest.

    Args:
      a: A set, as returned by `sets.make()`.
      b: A set, as returned by `sets.make()`.

    Returns:
      `a`, `b` if `a` is shorter than `b` - or `b`, `a` if `b` is shorter than `a`.
    """
    if _length(a) < _length(b):
        return a, b
    return b, a

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

    Args:
      a: A set, as returned by `sets.make()`.
      b: A set, as returned by `sets.make()`.

    Returns:
      True if `a` is equal to `b`, False otherwise.
    """
    return a._values == b._values

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

    Args:
      a: A set, as returned by `sets.make()`.
      b: A set, as returned by `sets.make()`.

    Returns:
      True if `a` is a subset of `b`, False otherwise.
    """
    for e in a._values.keys():
        if e not in b._values:
            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, as returned by `sets.make()`.
      b: A set, as returned by `sets.make()`.

    Returns:
      True if `a` and `b` are disjoint, False otherwise.
    """
    shorter, longer = _get_shorter_and_longer(a, b)
    for e in shorter._values.keys():
        if e in longer._values:
            return False
    return True

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

    Args:
      a: A set, as returned by `sets.make()`.
      b: A set, as returned by `sets.make()`.

    Returns:
      A set containing the elements that are in both `a` and `b`.
    """
    shorter, longer = _get_shorter_and_longer(a, b)
    return struct(_values = {e: None for e in shorter._values.keys() if e in longer._values})

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`.
    """
    return struct(_values = dicts.add(*[s._values for s in args]))

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

    Args:
      a: A set, as returned by `sets.make()`.
      b: A set, as returned by `sets.make()`.

    Returns:
      A set containing the elements that are in `a` but not in `b`.
    """
    return struct(_values = {e: None for e in a._values.keys() if e not in b._values})

def _length(s):
    """Returns the number of elements in a set.

    Args:
      s: A set, as returned by `sets.make()`.

    Returns:
      An integer representing the number of elements in the set.
    """
    return len(s._values)

def _repr(s):
    """Returns a string value representing the set.

    Args:
      s: A set, as returned by `sets.make()`.

    Returns:
      A string representing the set.
    """
    return repr(s._values.keys())

sets = struct(
    make = _make,
    copy = _copy,
    to_list = _to_list,
    insert = _insert,
    contains = _contains,
    is_equal = _is_equal,
    is_subset = _is_subset,
    disjoint = _disjoint,
    intersection = _intersection,
    union = _union,
    difference = _difference,
    length = _length,
    remove = _remove,
    repr = _repr,
    str = _repr,
)
