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

import("//third_party/closure_compiler/closure_args.gni")
import("//ui/webui/webui_features.gni")

script_path = "//third_party/closure_compiler"
compiler_path = "$script_path/compiler/compiler.jar"
externs_path = "$script_path/externs"
interfaces_path = "$script_path/interfaces"
chrome_externs = "$externs_path/chrome.js"
polymer_externs = "$externs_path/polymer-1.0.js"

# Defines a target that creates an ordering for .js files to be used by
# js_binary to compile.
#
# Variables:
#   sources:
#     List of Javascript files to include in the library. Uses target_name.js by
#     default.
#
#   deps:
#     List of js_library targets to depend on
#
#   extra_deps:
#     List of any other rules to depend on. E.g. a rule that generates js source
#     files
#
#   externs_list:
#     A list of .js files to pass to the compiler as externs
#
#   extra_sources:
#     A list of .js files to pass to the compiler as interfaces
#
# Example:
#   js_library("apple_tree") {
#     sources = ["tree_main.js"]
#     deps = [
#       ":branch",
#       ":trunk",
#       ":root",
#     ]
#   }

template("js_library") {
  action(target_name) {
    script = "$script_path/js_library.py"
    forward_variables_from(invoker,
                           [
                             "sources",
                             "deps",
                             "externs_list",
                             "extra_sources",
                             "extra_deps",
                           ])
    output_file = "$target_gen_dir/$target_name.js_library"
    outputs = [
      output_file,
    ]
    args = [ "--output" ] + [ rebase_path(output_file, root_build_dir) ]

    if (!defined(sources)) {
      sources = [
        target_name + ".js",
      ]
    }

    args += [ "--sources" ] + rebase_path(sources, root_build_dir)
    if (defined(extra_sources)) {
      args += rebase_path(extra_sources, root_build_dir)
      sources += extra_sources
    }

    if (defined(deps)) {
      args += [ "--deps" ]
      foreach(dep, deps) {
        # Get the output path for each dep
        dep_gen_dir = get_label_info(dep, "target_gen_dir")
        dep_name = get_label_info(dep, "name")
        dep_output_path = "$dep_gen_dir/$dep_name.js_library"
        args += [ rebase_path(dep_output_path, root_build_dir) ]
      }
    }
    if (defined(externs_list)) {
      args += [ "--externs" ] + rebase_path(externs_list, root_build_dir)
      sources += externs_list
    }
    if (defined(extra_deps)) {
      if (!defined(deps)) {
        deps = []
      }
      deps += extra_deps
    }
  }
}

# Defines a target that compiles javascript files using the Closure compiler.
# This will produce a minified javascript output file. Additional checks and
# optimizations can be configured using the closure_flags attribute.
#
# Variables:
#   sources:
#     List of .js files to compile. Will be target_name.js by default. Use
#     sources = [] to specify no input files (when making a target that just
#     group compiles other targets, for example).
#
#   deps:
#     List of js_library rules to depend on
#
#   outputs:
#     A file to write the compiled .js to.
#     Only takes in a single file, but must be placed in a list
#
#   bootstrap_file:
#      A .js files to include before all others
#
#   config_files:
#     A list of .js files to include after the bootstrap_file but before all
#     others
#
#   closure_flags:
#     A list of custom flags to pass to the Closure compiler.  Do not include
#     the leading dashes
#
#   externs_list:
#     A list of .js files to pass to the compiler as externs
#
# Example:
#   js_binary("tree") {
#     sources = ["tree_main.js"]
#     deps = [":apple_tree"]
#     outputs = [ "$target_gen_dir/tree.js" ]
#     bootstrap_file = "bootstrap.js"
#     config_files = [
#       "config1.js",
#       "config2.js",
#     ]
#     closure_flags = ["jscomp_error=undefinedVars"]
#     externs_list = [ "externs.js" ]
#   }

template("js_binary") {
  action(target_name) {
    script = "$script_path/js_binary.py"
    forward_variables_from(invoker,
                           [
                             "sources",
                             "deps",
                             "outputs",
                             "bootstrap_file",
                             "config_files",
                             "closure_flags",
                             "externs_list",
                             "extra_deps",
                             "checks_only",
                           ])
    args = [
      "--compiler",
      rebase_path(compiler_path, root_build_dir),
    ]

    if (!defined(outputs)) {
      outputs = [
        "$target_gen_dir/$target_name.js",
      ]
    }
    args += [ "--output" ] + rebase_path(outputs, root_build_dir)

    if (!defined(sources)) {
      sources = [
        "$target_name.js",
      ]
    }

    if (defined(deps)) {
      args += [ "--deps" ]
      foreach(dep, deps) {
        # Get the output path for each dep
        dep_gen_dir = get_label_info(dep, "target_gen_dir")
        dep_name = get_label_info(dep, "name")
        dep_output_path = "$dep_gen_dir/$dep_name.js_library"
        args += [ rebase_path(dep_output_path, root_build_dir) ]
      }
    }

    args += [ "--sources" ] + rebase_path(sources, root_build_dir)

    if (defined(bootstrap_file)) {
      args += [
        "--bootstrap",
        rebase_path(bootstrap_file, root_build_dir),
      ]
      sources += [ bootstrap_file ]
    }
    if (defined(config_files)) {
      args += [ "--config" ] + rebase_path(config_files, root_build_dir)
      sources += config_files
    }

    # |minifying_closure_args| from
    # //third_party/closure_compiler/closure_args.gni
    if (!defined(closure_flags)) {
      closure_flags = default_closure_args
    }
    if (defined(checks_only) && checks_only) {
      args += [ "--checks-only" ]
    }
    args += [ "--flags" ] + closure_flags
    args += [
      "--externs",
      rebase_path("$chrome_externs", root_build_dir),
      rebase_path("$polymer_externs", root_build_dir),
    ]
    if (defined(externs_list)) {
      args += rebase_path(externs_list, root_build_dir)
      sources += externs_list
    }

    if (defined(extra_deps)) {
      if (!defined(deps)) {
        deps = []
      }
      deps += extra_deps
    }
  }
}

# Defines a target that compiles a group of js_library targets.
template("js_type_check") {
  if (closure_compile) {
    js_binary(target_name) {
      sources = []
      checks_only = true
      forward_variables_from(invoker, [ "deps" ])
    }
  } else {
    not_needed(invoker, "*")
    group(target_name) {
    }
  }
}
