# 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_pigweed/legacy_target.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",
      ]
    }
  }
}
