# 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
#
#   extra_public_deps
#     List of other targets to expose as public dependencies.
#
#   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,
                           [
                             "deps",
                             "externs_list",
                             "extra_deps",
                             "extra_public_deps",
                             "extra_sources",
                             "sources",
                             "testonly",
                             "visibility",
                           ])
    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
    }
    if (defined(extra_public_deps)) {
      public_deps = extra_public_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,
                           [
                             "bootstrap_file",
                             "checks_only",
                             "closure_flags",
                             "config_files",
                             "deps",
                             "externs_list",
                             "extra_deps",
                             "outputs",
                             "is_polymer3",
                             "sources",
                             "testonly",
                           ])
    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
    }

    if (defined(checks_only) && checks_only) {
      args += [ "--checks-only" ]
    }

    if (!defined(is_polymer3)) {
      is_polymer3 = false
    }

    # |minifying_closure_args| from
    # //third_party/closure_compiler/closure_args.gni
    if (!defined(closure_flags)) {
      closure_flags = default_closure_args
    }
    if (is_polymer3) {
      closure_flags += polymer3_args
    }

    args += [ "--flags" ] + closure_flags
    args += [
      "--externs",
      rebase_path("$chrome_externs", root_build_dir),
    ]
    inputs = [
      "$script_path/closure_args.gni",
      chrome_externs,
      compiler_path,
    ]

    # |polymer_externs| should only be added for Polymer versions 1 and 2. For
    # Polymer3, Polymer sources are directly passed to the compiler instead.
    if (!is_polymer3) {
      args += [ rebase_path("$polymer_externs", root_build_dir) ]
      inputs += [ polymer_externs ]
    }

    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,
                             [
                               "closure_flags",
                               "deps",
                               "is_polymer3",
                               "testonly",
                             ])
    }
  } else {
    not_needed(invoker, "*")
    group(target_name) {
    }
  }
}
