# Copyright 2021 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Cxxbridge is a library that allows safe interop between Rust and C++. In order
# to integrate it into GN, we depend on the cxxbridge-cmd crate, which provides
# the cxxbridge binary used here. See https://cxx.rs/ for more information on
# cxx and https://crates.io/crates/cxxbridge-cmd for cxxbridge-cmd.

# Generate cxxbridge header only.
#
template("cxxbridge_header") {
  action_name = "${target_name}_gen"
  action_foreach(action_name) {
    forward_variables_from(invoker, [ "sources" ])
    assert(defined(sources), "sources must be set")

    script = "//common-mk/file_generator_wrapper.py"
    outformat = "{{source_gen_dir}}/{{source_file_part}}.h"
    args = [
      "cxxbridge",
      "{{source}}",
      "--header",
      "--output",
      outformat,
    ]
    outputs = [ outformat ]
  }

  all_dependent_config_name = "_${target_name}_all_dependent_config"
  config(all_dependent_config_name) {
    include_dirs = [ "${target_gen_dir}" ]
  }

  generated_file(target_name) {
    outputs = [ "${target_gen_dir}/${target_name}_gen_files.json" ]
    data_keys = [ "generated_cxxbridge_header" ]

    all_dependent_configs = [ ":${all_dependent_config_name}" ]

    if (defined(invoker.all_dependent_configs)) {
      all_dependent_configs += invoker.all_dependent_configs
    }

    deps = [ ":${action_name}" ]
    if (defined(invoker.deps)) {
      deps += invoker.deps
    }
  }
}

# Generate cxxbridge library header (rust/cxx.h).
template("cxxbridge_libheader") {
  action_name = "${target_name}_gen"
  action(action_name) {
    script = "//common-mk/file_generator_wrapper.py"
    outformat = "${target_gen_dir}/rust/cxx.h"
    args = [
      "cxxbridge",
      "--header",
      "--output",
      outformat,
    ]
    outputs = [ outformat ]
  }

  all_dependent_config_name = "_${target_name}_all_dependent_config"
  config(all_dependent_config_name) {
    include_dirs = [ "${target_gen_dir}" ]
  }

  generated_file(target_name) {
    outputs = [ "${target_gen_dir}/${target_name}_gen_files.json" ]
    data_keys = [ "generated_cxxbridge_header" ]
    all_dependent_configs = [ ":${all_dependent_config_name}" ]

    deps = [ ":${action_name}" ]
    if (defined(invoker.deps)) {
      deps += invoker.deps
    }
  }
}

# Generate cxxbridge code.
template("cxxbridge_cc") {
  action_name = "${target_name}_gen"
  action_foreach(action_name) {
    forward_variables_from(invoker, [ "sources" ])
    assert(defined(sources), "sources must be set")

    script = "//common-mk/file_generator_wrapper.py"
    outformat = "{{source_gen_dir}}/{{source_file_part}}.cc"
    args = [
      "cxxbridge",
      "{{source}}",
      "--output",
      outformat,
    ]
    outputs = [ outformat ]
  }

  source_set(target_name) {
    sources = get_target_outputs(":${action_name}")

    deps = [ ":${action_name}" ]
    if (defined(invoker.deps)) {
      deps += invoker.deps
    }

    if (defined(invoker.configs)) {
      configs += invoker.configs
    }
  }
}
