# Copyright 2022 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 functions for working with native.subpackages()
"""
_SUBPACKAGES_SUPPORTED = hasattr(native, "subpackages")

def _supported():
    return _SUBPACKAGES_SUPPORTED

def _check_supported():
    if not _SUBPACKAGES_SUPPORTED:
        fail("native.subpackages not supported in this version of Bazel.")

def _all(exclude = [], allow_empty = False, fully_qualified = True):
    """List all direct subpackages of the current package regardless of directory depth.

    The returned list contains all subpackages, but not subpackages of subpackages.

    Example:
    Assuming the following BUILD files exist:

        BUILD
        foo/BUILD
        foo/sub/BUILD
        bar/BUILD
        baz/deep/dir/BUILD

    If the current package is '//' all() will return ['//foo', '//bar',
    '//baz/deep/dir'].  //foo/sub is not included because it is a direct
    subpackage of '//foo' not '//'

    NOTE: fail()s if native.subpackages() is not supported.

    Args:
      exclude:          see native.subpackages(exclude)
      allow_empty:      see native.subpackages(allow_empty)
      fully_qualified:  It true return fully qualified Labels for subpackages,
          otherwise returns subpackage path relative to current package.

    Returns:
      A mutable sorted list containing all sub-packages of the current Bazel
      package.
    """
    _check_supported()

    subs = native.subpackages(include = ["**"], exclude = exclude, allow_empty = allow_empty)
    if fully_qualified:
        return [_fully_qualified(s) for s in subs]

    return subs

def _fully_qualified(relative_path):
    package_name = native.package_name()
    if package_name:
        return "//%s/%s" % (package_name, relative_path)
    return "//" + relative_path

def _exists(relative_path):
    """Checks to see if relative_path is a direct subpackage of the current package.

    Example:

        BUILD
        foo/BUILD
        foo/sub/BUILD

    If the current package is '//' (the top-level BUILD file):
        subpackages.exists("foo") == True
        subpackages.exists("foo/sub") == False
        subpackages.exists("bar") == False

    NOTE: fail()s if native.subpackages() is not supported in the current Bazel version.

    Args:
      relative_path: a path to a subpackage to test, must not be an absolute Label.

    Returns:
      True if 'relative_path' is a subpackage of the current package.
    """
    _check_supported()
    return relative_path in native.subpackages(include = [relative_path], allow_empty = True)

subpackages = struct(
    all = _all,
    exists = _exists,
    supported = _supported,
)
