# 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
    }
  }
}