# Copyright 2024 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.
"""Builders to make building complex objects easier."""

load("@bazel_skylib//lib:types.bzl", "types")

def _DepsetBuilder():
    """Create a builder for a depset."""

    # buildifier: disable=uninitialized
    self = struct(
        _order = [None],
        add = lambda *a, **k: _DepsetBuilder_add(self, *a, **k),
        build = lambda *a, **k: _DepsetBuilder_build(self, *a, **k),
        direct = [],
        get_order = lambda *a, **k: _DepsetBuilder_get_order(self, *a, **k),
        set_order = lambda *a, **k: _DepsetBuilder_set_order(self, *a, **k),
        transitive = [],
    )
    return self

def _DepsetBuilder_add(self, *values):
    """Add value to the depset.

    Args:
        self: {type}`DepsetBuilder` implicitly added.
        *values: {type}`depset | list | object` Values to add to the depset.
            The values can be a depset, the non-depset value to add, or
            a list of such values to add.

    Returns:
        {type}`DepsetBuilder`
    """
    for value in values:
        if types.is_list(value):
            for sub_value in value:
                if types.is_depset(sub_value):
                    self.transitive.append(sub_value)
                else:
                    self.direct.append(sub_value)
        elif types.is_depset(value):
            self.transitive.append(value)
        else:
            self.direct.append(value)
    return self

def _DepsetBuilder_set_order(self, order):
    """Sets the order to use.

    Args:
        self: {type}`DepsetBuilder` implicitly added.
        order: {type}`str` One of the {obj}`depset` `order` values.

    Returns:
        {type}`DepsetBuilder`
    """
    self._order[0] = order
    return self

def _DepsetBuilder_get_order(self):
    """Gets the depset order that will be used.

    Args:
        self: {type}`DepsetBuilder` implicitly added.

    Returns:
        {type}`str | None` If not previously set, `None` is returned.
    """
    return self._order[0]

def _DepsetBuilder_build(self):
    """Creates a {obj}`depset` from the accumulated values.

    Args:
        self: {type}`DepsetBuilder` implicitly added.

    Returns:
        {type}`depset`
    """
    if not self.direct and len(self.transitive) == 1 and self._order[0] == None:
        return self.transitive[0]
    else:
        kwargs = {}
        if self._order[0] != None:
            kwargs["order"] = self._order[0]
        return depset(direct = self.direct, transitive = self.transitive, **kwargs)

def _RunfilesBuilder():
    """Creates a `RunfilesBuilder`.

    Returns:
        {type}`RunfilesBuilder`
    """

    # buildifier: disable=uninitialized
    self = struct(
        add = lambda *a, **k: _RunfilesBuilder_add(self, *a, **k),
        add_targets = lambda *a, **k: _RunfilesBuilder_add_targets(self, *a, **k),
        build = lambda *a, **k: _RunfilesBuilder_build(self, *a, **k),
        files = _DepsetBuilder(),
        root_symlinks = {},
        runfiles = [],
        symlinks = {},
    )
    return self

def _RunfilesBuilder_add(self, *values):
    """Adds a value to the runfiles.

    Args:
        self: {type}`RunfilesBuilder` implicitly added.
        *values: {type}`File | runfiles | list[File] | depset[File] | list[runfiles]`
            The values to add.

    Returns:
        {type}`RunfilesBuilder`
    """
    for value in values:
        if types.is_list(value):
            for sub_value in value:
                _RunfilesBuilder_add_internal(self, sub_value)
        else:
            _RunfilesBuilder_add_internal(self, value)
    return self

def _RunfilesBuilder_add_targets(self, targets):
    """Adds runfiles from targets

    Args:
        self: {type}`RunfilesBuilder` implicitly added.
        targets: {type}`list[Target]` targets whose default runfiles
            to add.

    Returns:
        {type}`RunfilesBuilder`
    """
    for t in targets:
        self.runfiles.append(t[DefaultInfo].default_runfiles)
    return self

def _RunfilesBuilder_add_internal(self, value):
    if _is_file(value):
        self.files.add(value)
    elif types.is_depset(value):
        self.files.add(value)
    elif _is_runfiles(value):
        self.runfiles.append(value)
    else:
        fail("Unhandled value: type {}: {}".format(type(value), value))

def _RunfilesBuilder_build(self, ctx, **kwargs):
    """Creates a {obj}`runfiles` from the accumulated values.

    Args:
        self: {type}`RunfilesBuilder` implicitly added.
        ctx: {type}`ctx` The rule context to use to create the runfiles object.
        **kwargs: additional args to pass along to {obj}`ctx.runfiles`.

    Returns:
        {type}`runfiles`
    """
    return ctx.runfiles(
        transitive_files = self.files.build(),
        symlinks = self.symlinks,
        root_symlinks = self.root_symlinks,
        **kwargs
    ).merge_all(self.runfiles)

# Skylib's types module doesn't have is_file, so roll our own
def _is_file(value):
    return type(value) == "File"

def _is_runfiles(value):
    return type(value) == "runfiles"

builders = struct(
    DepsetBuilder = _DepsetBuilder,
    RunfilesBuilder = _RunfilesBuilder,
)
