# 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")

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),
    ]
  }
}

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}") {
    forward_variables_from(invoker,
                           [
                             "protocol",
                             "output",
                           ])
    scanner_args = [ "${invoker.variant}-header" ]
    if (invoker.core) {
      scanner_args += [ "-c" ]
    }
  }
}

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}") {
    forward_variables_from(invoker,
                           [
                             "protocol",
                             "output",
                           ])
    scanner_args = [ "private-code" ]
  }
}
