# 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 building a Docker image."""

load(
    ":filetype.bzl",
    deb_filetype = "deb",
    docker_filetype = "docker",
    tar_filetype = "tar",
)
load(
    "//tools/build_defs/hash:hash.bzl",
    _hash_tools = "tools",
    _sha256 = "sha256",
)
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")
load(
    ":path.bzl",
    "dirname",
    "strip_prefix",
    _canonicalize_path = "canonicalize",
    _join_path = "join",
)
load(":serialize.bzl", _serialize_dict = "dict_to_associative_list")

def _build_layer(ctx):
    """Build the current layer for appending it the base layer."""

    layer = ctx.new_file(ctx.label.name + ".layer")
    build_layer = ctx.executable.build_layer
    args = [
        "--output=" + layer.path,
        "--directory=" + ctx.attr.directory,
        "--mode=" + ctx.attr.mode,
    ]

    if ctx.attr.data_path:
        # If data_prefix is specified, then add files relative to that.
        data_path = _join_path(
            dirname(ctx.outputs.out.short_path),
            _canonicalize_path(ctx.attr.data_path),
        )
        args += [
            "--file=%s=%s" % (f.path, strip_prefix(f.short_path, data_path))
            for f in ctx.files.files
        ]
    else:
        # Otherwise, files are added without a directory prefix at all.
        args += [
            "--file=%s=%s" % (f.path, f.basename)
            for f in ctx.files.files
        ]

    args += ["--tar=" + f.path for f in ctx.files.tars]
    args += ["--deb=" + f.path for f in ctx.files.debs if f.path.endswith(".deb")]
    args += [
        "--link=%s:%s" % (k, ctx.attr.symlinks[k])
        for k in ctx.attr.symlinks
    ]
    arg_file = ctx.new_file(ctx.label.name + ".layer.args")
    ctx.file_action(arg_file, "\n".join(args))

    ctx.action(
        executable = build_layer,
        arguments = ["--flagfile=" + arg_file.path],
        inputs = ctx.files.files + ctx.files.tars + ctx.files.debs + [arg_file],
        outputs = [layer],
        use_default_shell_env = True,
        mnemonic = "DockerLayer",
    )
    return layer

# TODO(mattmoor): In a future change, we should establish the invariant that
# base must expose "docker_layers", possibly by hoisting a "docker_load" rule
# from a tarball "base".
def _get_base_artifact(ctx):
    if ctx.files.base:
        if hasattr(ctx.attr.base, "docker_layers"):
            # The base is the first layer in docker_layers if provided.
            return _get_layers(ctx, ctx.attr.base)[0]["layer"]
        if len(ctx.files.base) != 1:
            fail("base attribute should be a single tar file.")
        return ctx.files.base[0]

def _image_config(ctx, layer_names):
    """Create the configuration for a new docker image."""
    config = ctx.new_file(ctx.label.name + ".config")

    label_file_dict = _string_to_label(
        ctx.files.label_files,
        ctx.attr.label_file_strings,
    )

    labels = dict()
    for l in ctx.attr.labels:
        fname = ctx.attr.labels[l]
        if fname[0] == "@":
            labels[l] = "@" + label_file_dict[fname[1:]].path
        else:
            labels[l] = fname

    args = [
        "--output=%s" % config.path,
        "--entrypoint=%s" % ",".join(ctx.attr.entrypoint),
        "--command=%s" % ",".join(ctx.attr.cmd),
        "--labels=%s" % _serialize_dict(labels),
        "--env=%s" % _serialize_dict(ctx.attr.env),
        "--ports=%s" % ",".join(ctx.attr.ports),
        "--volumes=%s" % ",".join(ctx.attr.volumes),
    ]
    if ctx.attr.user:
        args += ["--user=" + ctx.attr.user]
    if ctx.attr.workdir:
        args += ["--workdir=" + ctx.attr.workdir]

    inputs = layer_names
    args += ["--layer=@" + l.path for l in layer_names]

    if ctx.attr.label_files:
        inputs += ctx.files.label_files

    base = _get_base_artifact(ctx)
    if base:
        args += ["--base=%s" % base.path]
        inputs += [base]

    ctx.action(
        executable = ctx.executable.create_image_config,
        arguments = args,
        inputs = inputs,
        outputs = [config],
        use_default_shell_env = True,
        mnemonic = "ImageConfig",
    )
    return config

def _metadata_action(ctx, layer, name, output):
    """Generate the action to create the JSON metadata for the layer."""
    rewrite_tool = ctx.executable.rewrite_tool

    label_file_dict = _string_to_label(
        ctx.files.label_files,
        ctx.attr.label_file_strings,
    )

    labels = dict()
    for l in ctx.attr.labels:
        fname = ctx.attr.labels[l]
        if fname[0] == "@":
            labels[l] = "@" + label_file_dict[fname[1:]].path
        else:
            labels[l] = fname

    args = [
        "--output=%s" % output.path,
        "--layer=%s" % layer.path,
        "--name=@%s" % name.path,
        "--entrypoint=%s" % ",".join(ctx.attr.entrypoint),
        "--command=%s" % ",".join(ctx.attr.cmd),
        "--labels=%s" % _serialize_dict(labels),
        "--env=%s" % _serialize_dict(ctx.attr.env),
        "--ports=%s" % ",".join(ctx.attr.ports),
        "--volumes=%s" % ",".join(ctx.attr.volumes),
    ]
    if ctx.attr.workdir:
        args += ["--workdir=" + ctx.attr.workdir]
    inputs = [layer, rewrite_tool, name]
    if ctx.attr.label_files:
        inputs += ctx.files.label_files

    # TODO(mattmoor): Does this properly handle naked tarballs?
    base = _get_base_artifact(ctx)
    if base:
        args += ["--base=%s" % base.path]
        inputs += [base]
    if ctx.attr.user:
        args += ["--user=" + ctx.attr.user]

    ctx.action(
        executable = rewrite_tool,
        arguments = args,
        inputs = inputs,
        outputs = [output],
        use_default_shell_env = True,
        mnemonic = "RewriteJSON",
    )

def _metadata(ctx, layer, name):
    """Create the metadata for the new docker image."""
    metadata = ctx.new_file(ctx.label.name + ".metadata")
    _metadata_action(ctx, layer, name, metadata)
    return metadata

def _compute_layer_name(ctx, layer):
    """Compute the layer's name.

    This function synthesize a version of its metadata where in place
    of its final name, we use the SHA256 of the layer blob.

    This makes the name of the layer a function of:
      - Its layer's SHA256
      - Its metadata
      - Its parent's name.
    Assuming the parent's name is derived by this same rigor, then
    a simple induction proves the content addressability.

    Args:
      ctx: Rule context.
      layer: The layer's artifact for which to compute the name.
    Returns:
      The artifact that will contains the name for the layer.
    """
    metadata = ctx.new_file(ctx.label.name + ".metadata-name")
    layer_sha = _sha256(ctx, layer)
    _metadata_action(ctx, layer, layer_sha, metadata)
    return _sha256(ctx, metadata)

def _repository_name(ctx):
    """Compute the repository name for the current rule."""
    if ctx.attr.legacy_repository_naming:
        # Legacy behavior, off by default.
        return _join_path(ctx.attr.repository, ctx.label.package.replace("/", "_"))

    # Newer Docker clients support multi-level names, which are a part of
    # the v2 registry specification.
    return _join_path(ctx.attr.repository, ctx.label.package)

def _create_image(ctx, layers, identifier, config, name, metadata, tags):
    """Create the new image."""
    args = [
        "--output=" + ctx.outputs.layer.path,
        "--id=@" + identifier.path,
        "--config=" + config.path,
    ] + ["--tag=" + tag for tag in tags]

    args += ["--layer=@%s=%s" % (l["name"].path, l["layer"].path) for l in layers]
    inputs = [identifier, config] + [l["name"] for l in layers] + [l["layer"] for l in layers]

    if name:
        args += ["--legacy_id=@" + name.path]
        inputs += [name]

    if metadata:
        args += ["--metadata=" + metadata.path]
        inputs += [metadata]

    # If we have been provided a base image, add it.
    if ctx.attr.base and not hasattr(ctx.attr.base, "docker_layers"):
        legacy_base = _get_base_artifact(ctx)
        if legacy_base:
            args += ["--legacy_base=%s" % legacy_base.path]
            inputs += [legacy_base]

    # TODO(mattmoor): Does this properly handle naked tarballs? (excl. above)
    base = _get_base_artifact(ctx)
    if base:
        args += ["--base=%s" % base.path]
        inputs += [base]
    ctx.action(
        executable = ctx.executable.create_image,
        arguments = args,
        inputs = inputs,
        outputs = [ctx.outputs.layer],
        mnemonic = "CreateImage",
    )

def _docker_build_impl(ctx):
    """Implementation for the docker_build rule."""
    layer = _build_layer(ctx)
    layer_sha = _sha256(ctx, layer)

    config = _image_config(ctx, [layer_sha])
    identifier = _sha256(ctx, config)

    name = _compute_layer_name(ctx, layer)
    metadata = _metadata(ctx, layer, name)

    # Construct a temporary name based on the build target.
    tags = [_repository_name(ctx) + ":" + ctx.label.name]

    # creating a partial image so only pass the layers that belong to it
    image_layer = {"layer": layer, "name": layer_sha}
    _create_image(ctx, [image_layer], identifier, config, name, metadata, tags)

    # Compute the layers transitive provider.
    # This must includes all layers of the image, including:
    #  - The layer introduced by this rule.
    #  - The layers transitively introduced by docker_build deps.
    #  - Layers introduced by a static tarball base.
    # This is because downstream tooling should just be able to depend on
    # the availability and completeness of this field.
    layers = [
        {"layer": ctx.outputs.layer, "id": identifier, "name": name},
    ] + _get_layers(ctx, ctx.attr.base)

    # Generate the incremental load statement
    _incr_load(
        ctx,
        layers,
        {
            tag_name: {"name": name, "id": identifier}
            for tag_name in tags
        },
        ctx.outputs.executable,
    )

    _assemble_image(
        ctx,
        reverse(layers),
        {tag_name: name for tag_name in tags},
        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([ctx.outputs.layer]),
        docker_layers = layers,
    )

docker_build_ = rule(
    implementation = _docker_build_impl,
    attrs = dict({
        "base": attr.label(allow_files = docker_filetype),
        "data_path": attr.string(),
        "directory": attr.string(default = "/"),
        "tars": attr.label_list(allow_files = tar_filetype),
        "debs": attr.label_list(allow_files = deb_filetype),
        "files": attr.label_list(allow_files = True),
        "legacy_repository_naming": attr.bool(default = False),
        "mode": attr.string(default = "0555"),
        "symlinks": attr.string_dict(),
        "entrypoint": attr.string_list(),
        "cmd": attr.string_list(),
        "user": attr.string(),
        "env": attr.string_dict(),
        "labels": attr.string_dict(),
        "ports": attr.string_list(),  # Skylark doesn't support int_list...
        "volumes": attr.string_list(),
        "workdir": attr.string(),
        "repository": attr.string(default = "bazel"),
        # Implicit dependencies.
        "label_files": attr.label_list(
            allow_files = True,
        ),
        "label_file_strings": attr.string_list(),
        "build_layer": attr.label(
            default = Label("//tools/build_defs/pkg:build_tar"),
            cfg = "host",
            executable = True,
            allow_files = True,
        ),
        "create_image": attr.label(
            default = Label("//tools/build_defs/docker:create_image"),
            cfg = "host",
            executable = True,
            allow_files = True,
        ),
        "rewrite_tool": attr.label(
            default = Label("//tools/build_defs/docker:rewrite_json"),
            cfg = "host",
            executable = True,
            allow_files = True,
        ),
        "create_image_config": attr.label(
            default = Label("//tools/build_defs/docker:create_image_config"),
            cfg = "host",
            executable = True,
            allow_files = True,
        ),
    }.items() + _hash_tools.items() + _layer_tools.items()),
    outputs = {
        "out": "%{name}.tar",
        "layer": "%{name}-layer.tar",
    },
    executable = True,
)

# This validates the two forms of value accepted by
# ENTRYPOINT and CMD, turning them into a canonical
# python list form.
#
# The Dockerfile construct:
#   ENTRYPOINT "/foo"
# Results in:
#   "Entrypoint": [
#       "/bin/sh",
#       "-c",
#       "\"/foo\""
#   ],
# Whereas:
#   ENTRYPOINT ["/foo", "a"]
# Results in:
#   "Entrypoint": [
#       "/foo",
#       "a"
#   ],
# NOTE: prefacing a command with 'exec' just ends up with the former
def _validate_command(name, argument):
    if type(argument) == "string":
        return ["/bin/sh", "-c", argument]
    elif type(argument) == "list":
        return argument
    elif argument:
        fail("The %s attribute must be a string or list, if specified." % name)
    else:
        return None

# Produces a new docker image tarball compatible with 'docker load', which
# is a single additional layer atop 'base'.  The goal is to have relatively
# complete support for building docker image, from the Dockerfile spec.
#
# For more information see the 'Config' section of the image specification:
# https://github.com/opencontainers/image-spec/blob/v0.2.0/serialization.md
#
# Only 'name' is required. All other fields have sane defaults.
#
#   docker_build(
#      name="...",
#      visibility="...",
#
#      # The base layers on top of which to overlay this layer,
#      # equivalent to FROM.
#      base="//another/build:rule",
#
#      # The base directory of the files, defaulted to
#      # the package of the input.
#      # All files structure relatively to that path will be preserved.
#      # A leading '/' mean the workspace root and this path is relative
#      # to the current package by default.
#      data_path="...",
#
#      # The directory in which to expand the specified files,
#      # defaulting to '/'.
#      # Only makes sense accompanying one of files/tars/debs.
#      directory="...",
#
#      # The set of archives to expand, or packages to install
#      # within the chroot of this layer
#      files=[...],
#      tars=[...],
#      debs=[...],
#
#      # The set of symlinks to create within a given layer.
#      symlinks = {
#          "/path/to/link": "/path/to/target",
#          ...
#      },
#
#      # https://docs.docker.com/reference/builder/#entrypoint
#      entrypoint="...", or
#      entrypoint=[...],            -- exec form
#
#      # https://docs.docker.com/reference/builder/#cmd
#      cmd="...", or
#      cmd=[...],                   -- exec form
#
#      # https://docs.docker.com/reference/builder/#expose
#      ports=[...],
#
#      # https://docs.docker.com/reference/builder/#user
#      # NOTE: the normal directive affects subsequent RUN, CMD,
#      # and ENTRYPOINT
#      user="...",
#
#      # https://docs.docker.com/reference/builder/#volume
#      volumes=[...],
#
#      # https://docs.docker.com/reference/builder/#workdir
#      # NOTE: the normal directive affects subsequent RUN, CMD,
#      # ENTRYPOINT, ADD, and COPY, but this attribute only affects
#      # the entry point.
#      workdir="...",
#
#      # https://docs.docker.com/reference/builder/#env
#      env = {
#         "var1": "val1",
#         "var2": "val2",
#         ...
#         "varN": "valN",
#      },
#   )
def docker_build(**kwargs):
    """Package a docker image.

    This rule generates a sequence of genrules the last of which is named 'name',
    so the dependency graph works out properly.  The output of this rule is a
    tarball compatible with 'docker save/load' with the structure:
      {layer-name}:
        layer.tar
        VERSION
        json
      {image-config-sha256}.json
      ...
      manifest.json
      repositories
      top     # an implementation detail of our rules, not consumed by Docker.
    This rule appends a single new layer to the tarball of this form provided
    via the 'base' parameter.

    The images produced by this rule are always named 'bazel/tmp:latest' when
    loaded (an internal detail).  The expectation is that the images produced
    by these rules will be uploaded using the 'docker_push' rule below.

    Args:
      **kwargs: See above.
    """
    if "cmd" in kwargs:
        kwargs["cmd"] = _validate_command("cmd", kwargs["cmd"])
    for reserved in ["label_files", "label_file_strings"]:
        if reserved in kwargs:
            fail("reserved for internal use by docker_build macro", attr = reserved)
    if "labels" in kwargs:
        files = sorted(depset([v[1:] for v in kwargs["labels"].values() if v[0] == "@"]))
        kwargs["label_files"] = files
        kwargs["label_file_strings"] = files
    if "entrypoint" in kwargs:
        kwargs["entrypoint"] = _validate_command("entrypoint", kwargs["entrypoint"])
    docker_build_(**kwargs)
