# Copyright 2019 The Fuchsia Authors
#
# 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("//build/compiled_action.gni")

# Private template to invoke the wayland-scanner tool using the provided arguments.
template("_wayland_protocol") {
  assert(defined(invoker.protocol),
         "${target_name} must have a 'protocol' property, e.g. 'wayland.xml'")
  assert(
      defined(invoker.output),
      "${target_name} must have an 'output' property, e.g. 'wayland-client-protocol-core.h'")
  compiled_action("${target_name}") {
    tool = "//third_party/wayland:scanner"
    tool_output_name = "wayland-scanner"
    sources = [
      invoker.protocol,
    ]
    outputs = [
      invoker.output,
    ]
    args = invoker.scanner_args
    args += [
      rebase_path(invoker.protocol, root_build_dir),
      rebase_path(invoker.output, root_build_dir),
    ]
  }
}

# Given a wayland protocol xml file, the wayland_protocol_header template generates a client or
# server header file, optionally with the '--include-core-only' generation flag.
template("wayland_protocol_header") {
  assert(defined(invoker.protocol),
         "${target_name} must have a 'protocol' property, e.g. 'wayland.xml'")
  assert(defined(invoker.variant),
         "${target_name} must have a 'variant' property, e.g. 'client'")
  assert(invoker.variant == "client" || invoker.variant == "server",
         "${target_name}.variant must be 'client' or 'server'")
  assert(defined(invoker.core),
         "${target_name} must have a 'core' property, e.g. 'true'")
  assert(
      defined(invoker.output),
      "${target_name} must have an 'output' property, e.g. 'wayland-client-protocol-core.h'")
  _wayland_protocol("_${target_name}_protocol") {
    forward_variables_from(invoker,
                           [
                             "protocol",
                             "output",
                           ])
    scanner_args = [ "${invoker.variant}-header" ]
    if (invoker.core) {
      scanner_args += [ "-c" ]
    }
  }
  config("_${target_name}_config") {
    forward_variables_from(invoker, "*")
    include_dirs = [ get_path_info(invoker.output, "dir") ]
  }
  group("${target_name}") {
    forward_variables_from(invoker, "*")
    deps = [ ":_${target_name}_protocol" ]
    public_configs = [ ":_${target_name}_config" ]
  }
}

# Given a wayland protocol xml file, the wayland_protocol_code template generates protocol
# marshalling code file using the 'private-code' argument as recommended in the wayland-scanner
# documentation.
template("wayland_protocol_code") {
  assert(defined(invoker.protocol),
         "${target_name} must have a 'protocol' property, e.g. 'wayland.xml'")
  assert(
      defined(invoker.output),
      "${target_name} must have an 'output' property, e.g. 'wayland-protocol.c'")
  _wayland_protocol("_${target_name}_protocol") {
    forward_variables_from(invoker,
                           [
                             "protocol",
                             "output",
                           ])
    scanner_args = [ "private-code" ]
  }
  source_set("_${target_name}_source_set") {
    forward_variables_from(invoker, "*")
    sources = [ invoker.output ]
    deps = [
      ":_${target_name}_protocol",
      "//third_party/wayland:client_headers",
      "//third_party/wayland:server_headers",
    ]
  }
  group("${target_name}") {
    forward_variables_from(invoker, "*")
    public_deps = [ ":_${target_name}_source_set" ]
  }
}
