# Copyright 2020 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

# gn-format disable
import("//build_overrides/pigweed.gni")

import("$dir_pw_toolchain/host_clang/toolchains.gni")
import("$dir_pw_unit_test/test.gni")

# Creates a libFuzzer-based fuzzer executable target.
#
# This will link `sources` and `deps` with the libFuzzer compiler runtime. The
# `sources` and `deps` should include a definition of the standard LLVM fuzz
# target function, `LLVMFuzzerTestOneInput`. For more details, see:
#   //pw_fuzzer/docs.rst
#   https://llvm.org/docs/LibFuzzer.html
#
template("pw_fuzzer") {
  # This currently is ONLY supported on Linux using clang (debug).
  # TODO(pwbug/179): Add Darwin, Windows here after testing.
  fuzzing_platforms = [ "linux" ]
  fuzzing_toolchains =
      [ get_path_info("$dir_pw_toolchain:host_clang_og", "abspath") ]

  # This is how GN says 'elem in list':
  can_fuzz = fuzzing_platforms + [ host_os ] - [ host_os ] != fuzzing_platforms
  can_fuzz = fuzzing_toolchains + [ current_toolchain ] -
             [ current_toolchain ] != fuzzing_toolchains && can_fuzz
  if (can_fuzz && pw_sanitizer != "") {
    # Build the actual fuzzer using the fuzzing config.
    pw_executable(target_name) {
      forward_variables_from(invoker, "*", [ "visibility" ])
      forward_variables_from(invoker, [ "visibility" ])
      if (!defined(configs)) {
        configs = []
      }
      configs += [
        "$dir_pw_fuzzer:default_config",
        "$dir_pw_fuzzer:sanitize_${pw_sanitizer}",
      ]
      if (oss_fuzz_enabled) {
        configs += [ "$dir_pw_fuzzer:oss_fuzz" ]
      } else {
        configs += [ "$dir_pw_fuzzer:fuzzing" ]
      }

      # Metadata for this fuzzer when used as part of a pw_test_group target.
      metadata = {
        tests = [
          {
            type = "fuzzer"
            test_name = target_name
            test_directory = rebase_path(target_out_dir, root_build_dir)
          },
        ]
      }
    }

    # Dummy target to satisfy `pw_test_group`. It is empty as we don't want to
    # automatically run fuzzers.
    group(target_name + "_run") {
    }
  } else {
    # Build a unit test that exercise the fuzz target function.
    pw_test(target_name) {
      # TODO(pwbug/195): Re-enable when there's better configurability for
      # on-device fuzz testing.
      enable_if = false
      sources = []
      deps = []
      forward_variables_from(invoker, "*", [ "visibility" ])
      forward_variables_from(invoker, [ "visibility" ])
      sources += [ "$dir_pw_fuzzer/pw_fuzzer_disabled.cc" ]
      if (!defined(configs)) {
        configs = []
      }
      configs += [ "$dir_pw_fuzzer:default_config" ]
      deps += [
        "$dir_pw_log",
        "$dir_pw_unit_test",
      ]
    }
  }
}
