# 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.
"""Rule for bundling Docker images into a tarball."""

load(":label.bzl", _string_to_label = "string_to_label")
load(
    ":layers.bzl",
    _assemble_image = "assemble",
    _get_layers = "get_from_target",
    _incr_load = "incremental_load",
    _layer_tools = "tools",
)
load(":list.bzl", "reverse")

def _docker_bundle_impl(ctx):
    """Implementation for the docker_bundle rule."""

    # Compute the set of layers from the image_targes.
    image_target_dict = _string_to_label(
        ctx.attr.image_targets,
        ctx.attr.image_target_strings,
    )

    seen_names = []
    layers = []
    for image in ctx.attr.image_targets:
        # TODO(mattmoor): Add support for naked tarballs.
        for layer in _get_layers(ctx, image):
            if layer["name"].path in seen_names:
                continue
            seen_names.append(layer["name"].path)
            layers.append(layer)

    images = dict()
    for unresolved_tag in ctx.attr.images:
        # Allow users to put make variables into the tag name.
        tag = ctx.expand_make_variables("images", unresolved_tag, {})

        target = ctx.attr.images[unresolved_tag]
        target = image_target_dict[target]
        images[tag] = _get_layers(ctx, target)[0]

    _incr_load(ctx, layers, images, ctx.outputs.executable)

    _assemble_image(ctx, reverse(layers), {
        # Create a new dictionary with the same keyspace that
        # points to the name of the layer.
        k: images[k]["name"]
        for k in images
    }, ctx.outputs.out)

    runfiles = ctx.runfiles(
        files = ([l["name"] for l in layers] +
                 [l["id"] for l in layers] +
                 [l["layer"] for l in layers]),
    )

    return struct(
        runfiles = runfiles,
        files = depset(),
    )

docker_bundle_ = rule(
    implementation = _docker_bundle_impl,
    attrs = dict({
        "images": attr.string_dict(),
        # Implicit dependencies.
        "image_targets": attr.label_list(allow_files = True),
        "image_target_strings": attr.string_list(),
    }.items() + _layer_tools.items()),
    outputs = {
        "out": "%{name}.tar",
    },
    executable = True,
)

# Produces a new docker image tarball compatible with 'docker load', which
# contains the N listed 'images', each aliased with their key.
#
# Example:
#   docker_bundle(
#     name = "foo",
#     images = {
#       "ubuntu:latest": ":blah",
#       "foo.io/bar:canary": "//baz:asdf",
#     }
#   )
def docker_bundle(**kwargs):
    """Package several docker images into a single tarball.

    Args:
      **kwargs: See above.
    """
    for reserved in ["image_targets", "image_target_strings"]:
        if reserved in kwargs:
            fail("reserved for internal use by docker_bundle macro", attr = reserved)

    if "images" in kwargs:
        kwargs["image_targets"] = kwargs["images"].values()
        kwargs["image_target_strings"] = kwargs["images"].values()

    docker_bundle_(**kwargs)
