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

# TODO(brettw) this should maybe be moved to tools/json_schema_compiler/ where
# the script is. Currently, we keep it in the build directory with the gyp
# version to make it easier to find.
#
# Or, considering the fact that it references the chrome/extensions directory,
# it should possibly be moved there.

_api_gen_dir = "//tools/json_schema_compiler"
_api_gen = "$_api_gen_dir/compiler.py"
_impl_dir = "chrome/browser/extensions/api"

_python_files = [
  "$_api_gen_dir/cc_generator.py",
  "$_api_gen_dir/code.py",
  "$_api_gen_dir/compiler.py",
  "$_api_gen_dir/cpp_bundle_generator.py",
  "$_api_gen_dir/cpp_type_generator.py",
  "$_api_gen_dir/cpp_util.py",
  "$_api_gen_dir/h_generator.py",
  "$_api_gen_dir/idl_schema.py",
  "$_api_gen_dir/json_schema.py",
  "$_api_gen_dir/model.py",
  "$_api_gen_dir/util_cc_helper.py",
]

# Runs the schema compiler over a list of sources.
#
# Parameters:
#   sources
#       The .json and .idl files to compile.
#
#   root_namespace
#       The C++ namespace that all generated files go under.
#
#   deps, visibility (optional)
template("json_schema_compile") {
  assert(defined(invoker.sources), "Need sources for $target_name")
  assert(defined(invoker.root_namespace),
         "Need root_namespace defined for $target_name")

  action_name = "${target_name}_action"
  source_set_name = target_name

  action_foreach(action_name) {
    visibility = ":$source_set_name"
    script = _api_gen

    source_prereqs = _python_files
    sources = invoker.sources

    # TODO(GYP) We should probably be using {{source_gen_dir}} instead of
    # $target_gen_dir but support for this string isn't pushed out in GN
    # binaries yet. Replace this when it is.
    outputs = [
      "$target_gen_dir/{{source_name_part}}.cc",
      "$target_gen_dir/{{source_name_part}}.h",
    ]

    args = [
      "--root", rebase_path("//", root_build_dir),
      "--destdir", rebase_path(root_gen_dir, root_build_dir),
      "--namespace", invoker.root_namespace,
      "--generator=cpp",
      "--impl-dir", _impl_dir,
      "{{source}}",
    ]
  }

  source_set(source_set_name) {
    if (defined(invoker.visibility)) {
      visibility = invoker.visibility
    }

    sources = get_target_outputs(":$action_name")

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

# Runs the schema bundler.
#
# Parameters:
#   sources
#       The .json and .idl files to bundle.
#
#   root_namespace
#       The C++ namespace that all generated files go under.
#
#   deps, visibility (optional)
template("json_schema_bundle") {
  assert(defined(invoker.sources), "Need sources for $target_name")
  assert(defined(invoker.root_namespace),
         "Need root_namespace defined for $target_name")

  action_name = "${target_name}_action"
  source_set_name = target_name

  action(action_name) {
    visibility = ":$source_set_name"
    script = _api_gen

    source_prereqs = _python_files
    source_prereqs += invoker.sources

    outputs = [
      "$target_gen_dir/generated_api.h",
      "$target_gen_dir/generated_api.cc",
      "$target_gen_dir/generated_schemas.h",
      "$target_gen_dir/generated_schemas.cc",
    ]

    args = [
      "--root", rebase_path("//", root_build_dir),
      "--destdir", rebase_path(root_gen_dir, root_build_dir),
      "--namespace", invoker.root_namespace,
      "--generator=cpp-bundle",
      "--impl-dir", _impl_dir,
    ] + rebase_path(invoker.sources, root_build_dir)
  }

  source_set(source_set_name) {
    if (defined(invoker.visibility)) {
      visibility = invoker.visibility
    }

    sources = get_target_outputs(":$action_name")

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