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

import("//build/host.gni")
import("//build/package.gni")

# TODO(aarongreen): SEC-224.  Add tests to catch fuzzer building/packaging
# regressions.

# Defines a fuzzer binary.
#
# The fuzzer template is used to create components containing binaries
# which leverage LLVM's libFuzzer to perform fuzz testing.
#
# Parameters are precisely those of an `executable`, along with:
#
#   options (optional)
#     [list of strings] Each option is of the form "key=value" and indicates
#     command line options that the fuzzer should be invoked with. Valid keys
#     are libFuzzer options (https://llvm.org/docs/LibFuzzer.html#options).
#
#   dictionary (optional)
#     [file] If specified, a file containing quoted inputs, one per line, that
#     the fuzzer will use to generate new mutations.
#
template("fuzzer") {
  fuzzer_name = target_name

  # Generate the component binary
  executable(fuzzer_name) {
    forward_variables_from(invoker,
                           "*",
                           [
                             "dictionary",
                             "options",
                             "visibility",
                           ])

    # Explicitly forward visibility for nested scopes.
    forward_variables_from(invoker, [ "visibility" ])
    testonly = true
    _target_type = "fuzzed_executable"
  }

  # Generate the fuzzer component manifest
  action("${fuzzer_name}_cmx") {
    script = "//build/fuzzing/gen_fuzzer_manifest.py"
    outputs = [
      "${target_gen_dir}/${fuzzer_name}.cmx",
    ]
    args = [
      "--out",
      rebase_path(outputs[0]),
      "--bin",
      fuzzer_name,
    ]
    if (defined(invoker.cmx)) {
      args += [
        "--cmx",
        rebase_path(invoker.cmx),
      ]
    }
  }

  # Generate data files needed at runtime
  output_dictionary = "${target_gen_dir}/${fuzzer_name}/dictionary"
  if (defined(invoker.dictionary)) {
    copy("${fuzzer_name}_dictionary") {
      sources = [
        invoker.dictionary,
      ]
      outputs = [
        output_dictionary,
      ]
    }
  } else {
    generated_file("${fuzzer_name}_dictionary") {
      contents = []
      outputs = [
        output_dictionary,
      ]
    }
  }
  generated_file("${fuzzer_name}_options") {
    contents = []
    if (defined(invoker.options)) {
      contents = invoker.options
    }
    outputs = [
      "${target_gen_dir}/${fuzzer_name}/options",
    ]
  }
}

set_defaults("fuzzer") {
  configs = default_executable_configs +
            [ "//build/fuzzing:fuzzing_build_mode_unsafe_for_production" ]
}

# Defines a package of fuzzers
#
# The fuzzers_package template is used to bundle several fuzzers and their
# associated data into a single Fuchsia package.
#
# Parameters
#
#   fuzzers (required)
#     [list of labels] The fuzzer() labels to include in this package.
#
#   sanitizers (optional)
#     [list of variants] A set of sanitizer variants.  The resulting package
#     will contain binaries for each sanitizer/fuzzer combination. Defaults to
#     [ "asan", "ubsan" ]
#
#   fuzz_host (optional)
#     [boolean] Indicates whether to also build fuzzer binaries on host.
#     Defaults to false.
#
#   meta (optional)
#   binaries (optional)
#   components (optional)
#   tests (optional)
#   drivers (optional)
#   loadable_modules (optional)
#   resources (optional)
#   extra (optional)
#     Same meanings as in //build/package.gni
#
#   deps (optional)
#   public_deps (optional)
#   data_deps (optional)
#   testonly (optional)
#     Usual GN meanings.
template("fuzzers_package") {
  assert(defined(invoker.fuzzers), "fuzzers must be defined for $target_name}")

  if (defined(invoker.sanitizers)) {
    sanitizers = invoker.sanitizers
  } else {
    sanitizers = [
      "asan",
      "ubsan",
    ]
  }

  if (defined(invoker.fuzz_host)) {
    fuzz_host = invoker.fuzz_host
  } else {
    fuzz_host = false
  }

  pkg = {
    meta = []
    binaries = []
    resources = []
    deps = []
    host_deps = []
    host_outputs = []
    metadata = {
      fuzzers_package = target_name
      fuzzers = []
      fuzz_host = fuzz_host
    }
  }

  # Collect the selected fuzzers listed in this package based on the variants
  # selected in args.gn and filtered by the package's list of supported
  # sanitizers.
  foreach(fuzzer, invoker.fuzzers) {
    selected = false
    foreach(sanitizer, sanitizers) {
      foreach(selector, select_variant_canonical) {
        if (!selected && selector.variant == "${sanitizer}-fuzzer" &&
            ((defined(selector.target_type) &&
              selector.target_type == [ "fuzzed_executable" ]) ||
             (defined(selector.name) && selector.name == [ fuzzer ]) ||
             (defined(selector.output_name) &&
              selector.output_name == [ fuzzer ]))) {
          selected = true
          fuzzer_name = get_label_info(fuzzer, "name")
          fuzzer_path = get_label_info(fuzzer, "target_gen_dir")
          fuzzer_label = get_label_info(fuzzer, "label_no_toolchain")
          pkg.meta += [
            {
              path = "${fuzzer_path}/${fuzzer_name}.cmx"
              dest = "${fuzzer_name}.cmx"
            },
          ]
          pkg.binaries += [
            {
              name = "${fuzzer_name}"
            },
          ]
          pkg.resources += [
            {
              path = "${fuzzer_path}/${fuzzer_name}/dictionary"
              dest = "${fuzzer_name}/dictionary"
            },
            {
              path = "${fuzzer_path}/${fuzzer_name}/options"
              dest = "${fuzzer_name}/options"
            },
          ]
          pkg.deps += [
            "${fuzzer_label}",
            "${fuzzer_label}_cmx",
            "${fuzzer_label}_dictionary",
            "${fuzzer_label}_options",
          ]
          if (fuzz_host) {
            pkg.deps += [ ":host_${target_name}" ]
            pkg.host_deps += [ fuzzer_label ]
            pkg.host_outputs += [ fuzzer_name ]
          }
          pkg_metadata = {
          }
          pkg_metadata = pkg.metadata
          pkg_metadata.fuzzers += [ fuzzer_name ]
        }
      }
    }
    not_needed([ "selected" ])
  }

  # Assemble the Fuchsia package
  if (pkg.deps != []) {
    package(target_name) {
      meta = []
      binaries = []
      resources = []
      deps = []
      forward_variables_from(invoker,
                             "*",
                             [
                               "metadata",
                               "sanitizers",
                               "visibility",
                             ])

      # Explicitly forward visibility for nested scopes.
      forward_variables_from(invoker, [ "visibility" ])
      testonly = true
      meta += pkg.meta
      binaries = pkg.binaries
      resources = pkg.resources
      deps = pkg.deps

      # This metadata will be used to generate out/default/fuzzers.json
      metadata = {
        if (defined(invoker.metadata)) {
          forward_variables_from(invoker.metadata, "*", [ "fuzz_spec" ])
        }
        fuzz_spec = [ pkg.metadata ]
      }
    }

    # Treat host fuzzers as tools. If we get to the point of having name
    # collisions, we'll need to extend `install_host_tools` to allow copying to
    # specific subdirectories of `host_tools_dir`
    if (fuzz_host) {
      install_host_tools("host_${target_name}") {
        testonly = true
        deps = pkg.host_deps
        outputs = pkg.host_outputs
      }
    }
  } else {
    # Dummy package for non-fuzzed builds
    group(target_name) {
    }
    not_needed(invoker, "*")
  }
}

# TODO(aarongreen): Complete soft transition and remove.
# These templates are the old names for `fuzzer` and `fuzzers_package`. They
# are included to allow third_party projects to transition softly.
template("fuzz_target") {
  source_set(target_name) {
  }
  not_needed(invoker, "*")
}

set_defaults("fuzz_target") {
  configs = []
}

template("fuzz_package") {
  group(target_name) {
  }
  not_needed(invoker, "*")
}
