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

import("//build/compiled_action.gni")
import("//build/fidl/toolchain.gni")
import("//build/sdk/sdk_atom_alias.gni")

# Generates some C++ bindings for a FIDL library.
#
# The parameters for this template are defined in //build/fidl/fidl.gni. The
# relevant parameters in this template are:
#   - name;
#   - sources;
template("fidl_cpp_codegen") {
  if (defined(invoker.sources)) {
    not_needed(invoker, [ "sources" ])
  }

  if (defined(invoker.public_deps)) {
    not_needed(invoker, [ "public_deps" ])
  }

  main_target_name = target_name
  generation_target_name =
      "${invoker.root_target}_${invoker.generator}_generate"

  library_name = target_name
  if (defined(invoker.name)) {
    library_name = invoker.name
  }

  fidl_target_gen_dir =
      get_label_info(":$target_name($fidl_toolchain)", "target_gen_dir")

  include_stem = string_replace(library_name, ".", "/") + "/" +
                 invoker.generated_source_base
  file_stem = "$fidl_target_gen_dir/$include_stem"

  fidl_target_name = invoker.root_target
  fidl_target_gen_dir =
      get_label_info(":${fidl_target_name}($fidl_toolchain)", "target_gen_dir")
  json_representation = "$fidl_target_gen_dir/$fidl_target_name.fidl.json"

  compiled_action(generation_target_name) {
    forward_variables_from(invoker, [ "testonly" ])

    visibility = [ ":$main_target_name" ]

    tool = invoker.fidlgen_tool

    inputs = [
      json_representation,
    ]

    outputs = [
      "$file_stem.h",
      "$file_stem.cc",
    ]

    args = [
      "--json",
      rebase_path(json_representation, root_build_dir),
      "--output-base",
      rebase_path(file_stem, root_build_dir),
      "--include-base",
      rebase_path(fidl_target_gen_dir, root_build_dir),
      "--generators",
      invoker.generator,
    ]

    deps = [
      ":$fidl_target_name($fidl_toolchain)",
    ]
  }
}

# Generates low-level C++ bindings for a library.
template("fidl_llcpp_codegen") {
  if (defined(invoker.sources)) {
    not_needed(invoker, [ "sources" ])
  }

  if (defined(invoker.public_deps)) {
    not_needed(invoker, [ "public_deps" ])
  }

  main_target_name = target_name
  generation_target_name =
      "${invoker.root_target}_llcpp_generate"

  library_name = target_name
  if (defined(invoker.name)) {
    library_name = invoker.name
  }

  fidl_target_gen_dir =
      get_label_info(":$target_name($fidl_toolchain)", "target_gen_dir")

  include_stem = string_replace(library_name, ".", "/") + "/" +
                 invoker.generated_source_base
  file_stem = "$fidl_target_gen_dir/$include_stem"

  fidl_target_name = invoker.root_target
  fidl_target_gen_dir =
      get_label_info(":${fidl_target_name}($fidl_toolchain)", "target_gen_dir")
  json_representation = "$fidl_target_gen_dir/$fidl_target_name.fidl.json"

  compiled_action(generation_target_name) {
    forward_variables_from(invoker, [ "testonly" ])

    visibility = [ ":$main_target_name" ]

    tool = "//garnet/go/src/fidl:fidlgen_llcpp"

    inputs = [
      json_representation,
    ]

    outputs = [
      "$file_stem.h",
      "$file_stem.cc",
    ]

    args = [
      "--json",
      rebase_path(json_representation, root_build_dir),
      "--header",
      rebase_path("$file_stem.h", root_build_dir),
      "--source",
      rebase_path("$file_stem.cc", root_build_dir),
      "--include-base",
      rebase_path(fidl_target_gen_dir, root_build_dir),
    ]

    deps = [
      ":$fidl_target_name($fidl_toolchain)",
    ]
  }
}

template("fidl_cpp_library") {
  not_needed(invoker, "*")

  main_target_name = target_name
  config_target_name = main_target_name + "__config"
  generation_target_name =
      "${invoker.root_target}_${invoker.generator}_generate"

  library_name = target_name
  if (defined(invoker.name)) {
    library_name = invoker.name
  }

  fidl_target_gen_dir =
      get_label_info(":$target_name($fidl_toolchain)", "target_gen_dir")

  include_stem = string_replace(library_name, ".", "/") + "/" +
                 invoker.generated_source_base
  file_stem = "$fidl_target_gen_dir/$include_stem"

  config(config_target_name) {
    include_dirs = [ fidl_target_gen_dir ]
  }

  source_set(main_target_name) {
    forward_variables_from(invoker,
                           [
                             "testonly",
                             "visibility",
                           ])

    sources = [
      "$file_stem.cc",
      "$file_stem.h",
    ]

    # Let dependencies use `#include "$file_stem.h"`.
    public_configs = [ ":$config_target_name" ]

    public_deps = [
      ":$generation_target_name($fidl_toolchain)",
      ":${invoker.root_target}($fidl_toolchain)",
      ":${invoker.root_target}_tables",
    ]

    foreach(dep, invoker.library_public_deps) {
      label = get_label_info(dep, "label_no_toolchain")
      public_deps += [ "${label}${invoker.target_suffix}" ]
    }

    public_deps += invoker.additional_public_deps

    if (defined(invoker.deps)) {
      public_deps += invoker.deps
    }
  }
}

template("fidl_cpp") {
  assert(defined(invoker.generators), "Need a list of generator tuples")
  not_needed(invoker, [
    "generators",
    "llcpp_generators"
  ])

  if (current_toolchain == fidl_toolchain) {
    library_name = target_name
    if (defined(invoker.name)) {
      library_name = invoker.name
    }

    foreach(generator_settings, invoker.generators) {
      if (defined(generator_settings.target_suffix)) {
        lib_name = "${target_name}_${generator_settings.target_suffix}"
      } else {
        lib_name = target_name
      }

      fidl_cpp_codegen(lib_name) {
        forward_variables_from(invoker, "*")
        name = library_name
        fidlgen_tool = generator_settings.fidlgen_tool
        generator = generator_settings.fidlgen_generator
        generated_source_base = generator_settings.output_stem
        root_target = target_name
      }
    }

    foreach(generator_settings, invoker.llcpp_generators) {
      if (defined(generator_settings.target_suffix)) {
        lib_name = "${target_name}_${generator_settings.target_suffix}"
      } else {
        lib_name = target_name
      }

      fidl_llcpp_codegen(lib_name) {
        forward_variables_from(invoker, "*")
        name = library_name
        generated_source_base = generator_settings.output_stem
        root_target = target_name
      }
    }
  } else {
    library_name = target_name
    if (defined(invoker.name)) {
      library_name = invoker.name
    }

    if (defined(invoker.sdk_category) && invoker.sdk_category != "excluded") {
      # Instead of depending on the generated bindings, set up a dependency on
      # the original library.
      sdk_target_name = "${target_name}_sdk"
      sdk_atom_alias(sdk_target_name) {
        atom = ":$sdk_target_name($fidl_toolchain)"
      }
    }

    foreach(generator_settings, invoker.generators + invoker.llcpp_generators) {
      library_public_deps = []
      if (defined(invoker.public_deps)) {
        library_public_deps += invoker.public_deps
      }

      if (defined(generator_settings.target_suffix)) {
        lib_name = "${target_name}_${generator_settings.target_suffix}"
        target_suffix = "_${generator_settings.target_suffix}"
      } else {
        lib_name = target_name
        target_suffix = ""
      }

      fidl_cpp_library(lib_name) {
        forward_variables_from(invoker, "*")
        name = library_name
        generator = generator_settings.fidlgen_generator
        generated_source_base = generator_settings.output_stem
        root_target = target_name
        additional_public_deps = generator_settings.additional_public_deps
      }
    }
  }
}
