# 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)
