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

load(":shared.bzl",
     "apple_action",
     "DARWIN_EXECUTION_REQUIREMENTS",
     "APPLE_FRAGMENTS")

def _compute_make_variables(resolved_srcs, files_to_build):
  variables = {"SRCS": cmd_helper.join_paths(" ", resolved_srcs),
               "OUTS": cmd_helper.join_paths(" ", files_to_build)}
  if len(resolved_srcs) == 1:
    variables["<"] = list(resolved_srcs)[0].path
  if len(files_to_build) == 1:
    variables["@"] = list(files_to_build)[0].path
  return variables


def _apple_genrule(ctx):
  resolved_srcs = set()
  if not ctx.outputs.outs:
    fail("apple_genrule must have one or more outputs", attr="outs")
  files_to_build = set(ctx.outputs.outs)

  if ctx.attr.executable and len(files_to_build) > 1:
    fail("if genrules produce executables, they are allowed only one output. "
          + "If you need the executable=1 argument, then you should split this "
          + "genrule into genrules producing single outputs",
         attr="executable")

  label_dict = {}
  for dep in ctx.attr.srcs:
    resolved_srcs += dep.files
    label_dict[dep.label] = dep.files

  resolved_inputs, argv, runfiles_manifests = ctx.resolve_command(
      command=ctx.attr.cmd,
      attribute="cmd",
      expand_locations=True,
      make_variables=_compute_make_variables(set(resolved_srcs), files_to_build),
      tools=ctx.attr.tools,
      label_dict=label_dict,
      execution_requirements=DARWIN_EXECUTION_REQUIREMENTS)

  message = ctx.attr.message or "Executing apple_genrule"

  env = ctx.configuration.default_shell_env
  env += ctx.fragments.apple.apple_host_system_env()

  apple_action(ctx,
               inputs=list(resolved_srcs) + resolved_inputs,
               outputs=list(files_to_build),
               env=env,
               command=argv,
               progress_message="%s %s" % (message, ctx),
               mnemonic="Genrule",
               input_manifests=runfiles_manifests)

  return struct(files=files_to_build,
                data_runfiles=ctx.runfiles(transitive_files=files_to_build))


_apple_genrule_inner = rule(
    implementation=_apple_genrule,
    attrs={
        "srcs": attr.label_list(allow_files=True),
        "tools": attr.label_list(cfg="host", allow_files=True),
        "outs": attr.output_list(mandatory=True),
        "cmd": attr.string(mandatory=True),
        "message": attr.string(),
        "output_licenses": attr.license(),
        "executable": attr.bool(default=False),
        },
    output_to_genfiles = True,
    fragments=APPLE_FRAGMENTS)

"""Genrule which provides Apple specific environment and make variables.
This mirrors the native genrule except that it provides a different set of
make variables. This rule will only run on a Mac.

Example of use:

load("//tools/build_defs/apple/apple_genrule.bzl", "apple_genrule")

apple_genrule(
    name = "world",
    outs = ["hi"],
    cmd = "touch $(@)",
)

This rule also does location expansion, much like the native genrule.
For example, $(location hi) may be used to refer to the output in the
above example.

The set of make variables that are supported for this rule:

OUTS: The outs list. If you have only one output file, you can also use $@.
SRCS: The srcs list (or more precisely, the pathnames of the files
      corresponding to labels in the srcs list). If you have only one source
      file, you can also use $<.
<: srcs, if it's a single file.
@: outs, if it's a single file.

The following environment variables are added to the rule action:

DEVELOPER_DIR: The base developer directory as defined on Apple architectures,
               most commonly used in invoking Apple tools such as xcrun.
"""
def apple_genrule(
    name,
    cmd,
    executable = False,
    outs = [],
    **kwargs):
  if executable:
    if len(outs) != 1:
      fail("apple_genrule, if executable, must have exactly one output")
    intermediate_out = outs[0] + "_nonexecutable"
    _apple_genrule_inner(
        name = name + "_nonexecutable",
        outs = [intermediate_out],
        cmd = cmd,
        **kwargs)
    native.genrule(
        name = name,
        outs = outs,
        srcs = [intermediate_out],
        cmd = "cp $< $@",
        executable = True,
    )
  else:
    _apple_genrule_inner(
        name = name,
        outs = outs,
        cmd = cmd,
        **kwargs)

