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

# Defines a static library corresponding to the output of schema compiler tools
# over a set of extensions API schemas (IDL or JSON format.) The library target
# has implicit hard dependencies on all schema files listed by the invoker and
# is itself a hard dependency.
#
# Invocations of this template may use the following variables:
#
# sources [required] A list of schema files to be compiled.
#
# root_namespace [required] The namespace in which generated API code is to be
#   wrapped. C++ namespace syntax is accepted for nested namespace
#   (e.g. "foo::bar::api").
#
# impl_dir [required] The path containing C++ implementations of API functions.
#   This path is used as the root path when looking for
#   {schema}/{schema}_api.h headers during the API bundle generation phase.
#   Such headers, if found, are automatically included by the generated code.
#
# uncompiled_sources [optional] A list of schema files which should not be
#   compiled, but which should still be processed for API bundle generation.
#
# deps [optional] If any deps are specified they will be inherited by the
#   static library target.
#
# The static libarary target also inherits the visibility and output_name
# of its invoker.

template("generated_extensions_api") {
  assert(defined(invoker.sources),
         "\"sources\" must be defined for the $target_name template.")
  assert(defined(invoker.root_namespace),
         "\"root_namespace\" must be defined for the $target_name template.")
  assert(defined(invoker.impl_dir),
         "\"impl_dir\" must be defined for the $target_name template.")

  # Keep a copy of the target_name here since it will be trampled
  # in nested targets.
  target_visibility = ":$target_name"

  generated_config_name = target_name + "_generated_config"
  config(generated_config_name) {
    include_dirs = [ target_gen_dir ]
    visibility = target_visibility
  }

  schemas = invoker.sources
  root_namespace = invoker.root_namespace
  impl_dir = invoker.impl_dir
  uncompiled_schemas = []
  if (defined(invoker.uncompiled_sources)) {
    uncompiled_schemas = invoker.uncompiled_sources
  }

  compiler_root = "//tools/json_schema_compiler"
  compiler_script = "$compiler_root/compiler.py"
  compiler_sources = [
    "$compiler_root/cc_generator.py",
    "$compiler_root/code.py",
    "$compiler_root/compiler.py",
    "$compiler_root/cpp_generator.py",
    "$compiler_root/cpp_type_generator.py",
    "$compiler_root/cpp_util.py",
    "$compiler_root/h_generator.py",
    "$compiler_root/idl_schema.py",
    "$compiler_root/model.py",
    "$compiler_root/util_cc_helper.py",
  ]

  schema_generator_name = target_name + "_schema_generator"
  action_foreach(schema_generator_name) {
    script = compiler_script
    source_prereqs = compiler_sources
    sources = schemas
    outputs = [
      "$target_gen_dir/{{source_name_part}}.cc",
      "$target_gen_dir/{{source_name_part}}.h",
    ]
    args = [
      "{{source}}",
      "--root=" + rebase_path("//", root_build_dir),
      "--destdir=" + rebase_path(root_gen_dir, root_build_dir),
      "--namespace=$root_namespace",
      "--generator=cpp" ]
    visibility = target_visibility
  }

  bundle_generator_name = target_name + "_bundle_generator"
  action(bundle_generator_name) {
    script = compiler_script
    source_prereqs = compiler_sources + schemas + uncompiled_schemas
    outputs = [
      "$target_gen_dir/generated_api.cc",
      "$target_gen_dir/generated_api.h",
      "$target_gen_dir/generated_schemas.cc",
      "$target_gen_dir/generated_schemas.h",
    ]
    args = [
      "--root=" + rebase_path("//", root_build_dir),
      "--destdir=" + rebase_path(root_gen_dir, root_build_dir),
      "--namespace=$root_namespace",
      "--generator=cpp-bundle",
      "--impl-dir=" + rebase_path(impl_dir, "//"),
    ] +
      rebase_path(schemas, root_build_dir) +
      rebase_path(uncompiled_schemas, root_build_dir)
  }

  source_set(target_name) {
    sources =
      get_target_outputs(":$schema_generator_name") +
      get_target_outputs(":$bundle_generator_name")

    deps = [
      ":$schema_generator_name",
      ":$bundle_generator_name",
      "//tools/json_schema_compiler:generated_api_util",
    ]

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

    if (defined(invoker.visibility)) {
      visibility = invoker.visibility
    }
    if (defined(invoker.output_name)) {
      output_name = invoker.output_name
    }
  }
}
