# Copyright 2018 The Fuchsia 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 set of Go code that can be used by other Go targets
#
# Parameters
#
#   name (optional)
#     Name of the Go package.
#     Defaults to "go.fuchsia.dev/fuchsia/${source_dir}".
#
#   name_file (optional)
#     Path to a file containing the name of the Go package.
#     This should be used when the package's name requires some computation in
#     its own build target.
#
#     NOTE: Exactly one of `name` or `name_file` may be set, but not both.
#           If neither is set, then the target name is used.
#
#   source_dir (optional)
#     Path to the root of the sources for the package.
#     Defaults to the current directory.
#
#   sources (optional)
#     List of source files, relative to source_dir.
#     TODO(fxbug.dev/3037): make this attribute required.
#
#   allow_globbing (optional)
#     Allows a library to include all its sources without listing them.
#     This limits what the GN dependency graph keeps track of and should
#     only be used by third-party libraries. Defaults to false.
#
#   deps (optional)
#     List of labels for Go libraries this target depends on.
#
#   non_go_deps (optional)
#     List of labels for non-Go targets this library depends on.
#
#   public_non_go_deps (optional)
#     List of labels for non-Go targets this library publicly depends on.
#
#   metadata (optional)
#     Scope giving the metadata of this library.
#
template("go_library") {
  assert(!(defined(invoker.name) && defined(invoker.name_file)),
         "Defining both name and name_file is not allowed")

  source_dir = "."
  if (defined(invoker.source_dir)) {
    source_dir = invoker.source_dir
  }

  if (defined(invoker.name)) {
    name_args = [
      "--name",
      invoker.name,
    ]
  } else if (defined(invoker.name_file)) {
    # Make name_file a system-absolute path and add it to args.
    name_args = [
      "--name-file",
      rebase_path(invoker.name_file),
    ]
  } else {
    target_name_dir = get_label_info(":$target_name", "dir")
    source_dir = rebase_path(source_dir, target_name_dir)
    name_args = [
      "--name",
      "go.fuchsia.dev/fuchsia/" + rebase_path(source_dir, "//"),
    ]
  }

  action(target_name) {
    hermetic_deps = false
    script = "//build/go/gen_library_metadata.py"

    library_file = "$target_gen_dir/$target_name.go_deps"

    outputs = [ library_file ]

    deps = []
    dependent_libraries = []

    if (defined(invoker.deps)) {
      deps += invoker.deps
      foreach(dep, invoker.deps) {
        gen_dir = get_label_info(dep, "target_gen_dir")
        name = get_label_info(dep, "name")
        dependent_libraries += [ "$gen_dir/$name.go_deps" ]
      }
    }

    if (defined(invoker.non_go_deps)) {
      deps += invoker.non_go_deps
    }

    public_deps = []
    if (defined(invoker.public_deps)) {
      public_deps += invoker.public_deps
    }
    if (defined(invoker.public_non_go_deps)) {
      public_deps += invoker.public_non_go_deps
    }

    inputs = dependent_libraries

    args = name_args + [
             "--source-dir",
             rebase_path(source_dir),
             "--output",
             rebase_path(library_file),
             "--deps",
           ] + rebase_path(dependent_libraries)

    if (defined(invoker.allow_globbing) && invoker.allow_globbing) {
      assert(!defined(invoker.sources),
             "sources cannot be listed when globbing is enabled")
      args += [ "--allow-globbing" ]
      deps += [ "//build/go:globbing_allowlist" ]
    } else {
      assert(defined(invoker.sources) && invoker.sources != [],
             "sources must be listed")
      args += [ "--sources" ] + invoker.sources
      inputs += rebase_path(invoker.sources, ".", source_dir)
    }

    if (defined(invoker.metadata)) {
      metadata = invoker.metadata
    }

    forward_variables_from(invoker,
                           [
                             "testonly",
                             "visibility",
                           ])
  }
}
