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

# Rules for templating / files layout

def _expand_template_impl(ctx):
  """Simply spawn the template-engine in a rule."""
  variables = [
      "--variable=%s=%s" % (k, ctx.attr.substitutions[k])
      for k in ctx.attr.substitutions
  ]
  d = {str(ctx.attr.deps[i].label): ctx.files.deps[i].path
       for i in range(0, len(ctx.attr.deps))}
  imports = ["--imports=%s=%s" % (k, d[k]) for k in d]
  imports += ["--imports=%s=%s" % (k, d[str(ctx.label.relative(ctx.attr.deps_aliases[k]))])
              for k in ctx.attr.deps_aliases]
  ctx.action(
      executable = ctx.executable._engine,
      arguments = [
        "--executable" if ctx.attr.executable else "--noexecutable",
        "--template=%s" % ctx.file.template.path,
        "--output=%s" % ctx.outputs.out.path,
      ] + variables + imports,
      inputs = [ctx.file.template] + ctx.files.deps,
      outputs = [ctx.outputs.out],
      )

expand_template = rule(
    attrs = {
        "template": attr.label(
            mandatory = True,
            allow_files = True,
            single_file = True,
        ),
        "deps": attr.label_list(default = [], allow_files = True),
        "deps_aliases": attr.string_dict(default = {}),
        "substitutions": attr.string_dict(mandatory = True),
        "out": attr.output(mandatory = True),
        "executable": attr.bool(default = True),
        "_engine": attr.label(
            default = Label("//templating:template_engine"),
            executable = True,
            cfg="host"),
    },
    implementation = _expand_template_impl,
)
"""Expand a jinja2 template file.

This rules expands the file given in template, into the file given by out.

Args:
  template: The template file to expand.
  deps: additional files to expand, they will be accessible as imports[label]
      in the template environment. If a file ends with .tpl, it is considered
      a template itself and will be expanded.
  deps_aliases: a dictionary of name to label. Each label in that dictionary
      should be present in the deps attribute, and will be make accessible as
      imports[name] in the template environment.
  substitutions: a dictionary of key => values that will appear as variables.key
      in the template environment.
  out: the name of the output file to generate.
  executable: mark the result as excutable if set to True.
"""

def strip_prefix(path, prefixes):
  for prefix in prefixes:
    if path.startswith(prefix):
      return path[len(prefix):]
  return path

def strip_suffix(path, suffixes):
  for suffix in suffixes:
    if path.endswith(suffix):
      return path[:-len(suffix)]
  return path

def _dest_path(f, strip_prefixes, strip_suffixes):
  """Returns the short path of f, stripped of strip_prefixes and strip_suffixes."""
  return strip_suffix(strip_prefix(f.short_path, strip_prefixes), strip_suffixes)

def _format_path(path_format, path):
  dirsep = path.rfind("/")
  dirname = path[:dirsep] if dirsep > 0 else ""
  basename = path[dirsep+1:] if dirsep > 0 else path
  extsep = basename.rfind(".")
  extension = basename[extsep+1:] if extsep > 0 else ""
  basename = basename[:extsep] if extsep > 0 else basename
  return path_format.format(
      path=path,
      dirname=dirname,
      basename=basename,
      extension=extension
  )

def _append_inputs(args, inputs, f, path, path_format):
  args.append("--file=%s=%s" % (
      f.path,
      _format_path(path_format, path)
  ))
  inputs.append(f)

def _merge_files_impl(ctx):
  """Merge a list of config files in a tar ball with the correct layout."""
  output = ctx.outputs.out
  build_tar = ctx.executable._build_tar
  inputs = []
  args = [
      "--output=" + output.path,
      "--directory=" + ctx.attr.directory,
      "--mode=0644",
      ]
  variables = [
      "--variable=%s=%s" % (k, ctx.attr.substitutions[k])
      for k in ctx.attr.substitutions
  ]
  for f in ctx.files.srcs:
    path = _dest_path(f, ctx.attr.strip_prefixes, ctx.attr.strip_suffixes)
    if path.endswith(ctx.attr.template_extension):
      path = path[:-4]
      f2 = ctx.new_file(ctx.label.name + "/" + path)
      ctx.action(
          executable = ctx.executable._engine,
          arguments = [
            "--template=%s" % f.path,
            "--output=%s" % f2.path,
            "--noescape_xml",
          ] + variables,
          inputs = [f],
          outputs = [f2],
      )
      _append_inputs(args, inputs, f2, path, ctx.attr.path_format)
    else:
      _append_inputs(args, inputs, f, path, ctx.attr.path_format)
  ctx.action(
      executable = build_tar,
      arguments = args,
      inputs = inputs,
      outputs = [output],
      mnemonic="MergeFiles"
      )

merge_files = rule(
    attrs = {
        "srcs": attr.label_list(allow_files=True),
        "template_extension": attr.string(default=".tpl"),
        "directory": attr.string(default="/"),
        "strip_prefixes": attr.string_list(default=[]),
        "strip_suffixes": attr.string_list(default=["-staging", "-test"]),
        "substitutions": attr.string_dict(default={}),
        "path_format": attr.string(default="{path}"),
        "_build_tar": attr.label(
            default=Label("@bazel_tools//tools/build_defs/pkg:build_tar"),
            cfg="host",
            executable=True,
            allow_files=True),
        "_engine": attr.label(
            cfg="host",
            default = Label("//templating:template_engine"),
            executable = True),
    },
    outputs = {"out": "%{name}.tar"},
    implementation = _merge_files_impl,
)
"""Merge a set of files in a single tarball.

This rule merge a set of files into one tarball, each file will appear in the
tarball as a file determined by path_format, strip_prefixes and directory.

Outputs:
  <name>.tar: the tarball containing all the files in srcs.

Args:
  srcs: The list of files to merge. If a file is ending with ".tpl" (see
      template_extension), it will get expanded like a template passed to
      expand_template.
  template_extension: extension of files to be considered as template, ".tpl"
      by default.
  directory: base directory for all the files in the resulting tarball.
  strip_prefixes: list of prefixes to strip from the path of the srcs to obtain
      the final path (see path_format).
  strip_suffixes: list of suffixes to strip from the path of the srcs to obtain
      the final path (see path_format).
  substitutions: map of substitutions to make available during template
      expansion. Values of that map will be available as "variables.name" in
      the template environment.
  path_format: format of the final files. Each file will appear in the final
      tarball under "{directory}/{path_format}" where the following string of
      path_format are replaced:
          {path}: path of the input file, removed from prefixes and suffixes,
          {dirname}: directory name of path,
          {basename}: base filename of path,
          {extension}: extension of path
"""
