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

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" ]
      deps += [ "$dir_pw_fuzzer:run_as_unit_test" ]
    }
  }
}
