# Copyright 2018 Google, LLC
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.

import("//src/graphics/lib/magma/gnbuild/magma.gni")

mesa_build_root = "//third_party/mesa"

template("mesa_source_set") {
  source_set(target_name) {
    # Can't forward configs because doing so overwrites the default
    # configs specified by the build system.
    forward_variables_from(invoker, "*", [ "configs" ])
    if (!defined(public_configs)) {
      public_configs = []
    }
    public_configs += [ "//third_party/mesa/src:common_config" ]
    if (defined(invoker.configs)) {
      configs += invoker.configs
    }
  }
}

# Executes a python script and writes its output to a file.
#
# Parameters
# * script
#   - Required: The .py file that will be interpreted.
#   - Type: path.
#
# * args
#   - Optional: Arguments to pass to the script.
#   - Type: list(str).
#
#  * output
#   - Required: Path to the output file. Assumed to be relative to ${target_gen_dir}.
#   - Type: path.
#
#  * pythonpath
#    - Optional: Used as PYTHONPATH environment variable. Defaults to ${magma_python_path}.
#    - Type: str.
#
# Other parameters have the same meaning as for action().

template("mesa_python_stdout_to_file_action") {
  assert(defined(invoker.script), "script is required")
  assert(defined(invoker.output), "output is required")
  action(target_name) {
    forward_variables_from(invoker,
                           "*",
                           [
                             "args",
                             "inputs",
                             "output",
                             "outputs",
                             "pythonpath",
                             "script",
                           ])

    hermetic_deps = false

    script = "${mesa_build_root}/scripts/gn_script_wrapper.sh"

    output = "${target_gen_dir}/${invoker.output}"

    if (defined(invoker.pythonpath)) {
      pythonpath = invoker.pythonpath
      inputs = []
    } else {
      pythonpath = magma_python_path

      # Some file that we can use as a signal that the other files
      # in magma_python_path have changed.
      inputs = [ "${magma_python_path}/doc/build/changelog.rst" ]
    }

    args = [
      rebase_path(python_exe_src, root_build_dir),
      pythonpath,
      rebase_path(output, root_build_dir),
      rebase_path(invoker.script, root_build_dir),
    ]
    if (defined(invoker.args)) {
      args += invoker.args
    }

    inputs += [ invoker.script ]
    if (defined(invoker.inputs)) {
      inputs += invoker.inputs
    }

    outputs = [ output ]
    if (defined(invoker.outputs)) {
      outputs += invoker.outputs
    }
  }
}

# Executes a python script with PYTHONPATH=${magma_python_path}
#
# Parameters
# Same as for action().

template("mesa_python_action") {
  action(target_name) {
    forward_variables_from(invoker,
                           "*",
                           [
                             "args",
                             "inputs",
                             "script",
                           ])

    script = "${mesa_build_root}/scripts/gn_script_wrapper.sh"

    args = [
      rebase_path(python_exe_src, root_build_dir),
      magma_python_path,

      # path to write stdout to, which we don't need.
      "/dev/stdout",
      rebase_path(invoker.script, root_build_dir),
    ]
    if (defined(invoker.args)) {
      args += invoker.args
    }

    inputs = [
      invoker.script,

      # Some file that we can use as a signal that the other files
      # in magma_python_path have changed.
      "${magma_python_path}/doc/build/changelog.rst",
    ]
    if (defined(invoker.inputs)) {
      inputs += invoker.inputs
    }
  }
}
