# Copyright 2018 The Dawn & Tint Authors
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
#    list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
#    contributors may be used to endorse or promote products derived from
#    this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import("../../../scripts/dawn_overrides_with_defaults.gni")

if (dawn_has_fuzzers) {
  import("//build_overrides/build.gni")
  import("//testing/libfuzzer/fuzzer_test.gni")
  import("${dawn_root}/scripts/dawn_features.gni")
  import("${dawn_root}/src/dawn/fuzzers/dawn_fuzzers.gni")

  static_library("dawn_wire_server_fuzzer_common") {
    sources = [
      "DawnWireServerFuzzer.cpp",
      "DawnWireServerFuzzer.h",
    ]
    public_deps = [
      "${dawn_root}/include/dawn:cpp_headers",
      "${dawn_root}/src/dawn:proc",
      "${dawn_root}/src/dawn/common",
      "${dawn_root}/src/dawn/native:static",
      "${dawn_root}/src/dawn/utils",
      "${dawn_root}/src/dawn/wire:static",
    ]
  }

  fuzzer_test("dawn_wire_server_and_frontend_fuzzer") {
    sources = [ "DawnWireServerAndFrontendFuzzer.cpp" ]

    deps = [ ":dawn_wire_server_fuzzer_common" ]

    additional_configs = [ "${dawn_root}/src/dawn/common:internal_config" ]
  }

  if (is_win) {
    fuzzer_test("dawn_wire_server_and_d3d12_backend_fuzzer") {
      sources = [ "DawnWireServerAndD3D12BackendFuzzer.cpp" ]

      deps = [ ":dawn_wire_server_fuzzer_common" ]

      additional_configs = [ "${dawn_root}/src/dawn/common:internal_config" ]
    }
  }

  fuzzer_test("dawn_wire_server_and_vulkan_backend_fuzzer") {
    sources = [ "DawnWireServerAndVulkanBackendFuzzer.cpp" ]

    deps = [ ":dawn_wire_server_fuzzer_common" ]

    additional_configs = [ "${dawn_root}/src/dawn/common:internal_config" ]
  }

  if (is_dawn_lpm_fuzzer && build_with_chromium && dawn_use_swiftshader &&
      !disable_libfuzzer && use_fuzzing_engine) {
    import("//third_party/protobuf/proto_library.gni")
    import("${dawn_root}/generator/dawn_generator.gni")

    # Generate the fuzzer's serializer in `.cpp`
    dawn_json_lpm_generator("dawn_lpmfuzz_cpp") {
      target = "dawn_lpmfuzz_cpp"
      outputs = [
        "src/dawn/fuzzers/lpmfuzz/DawnLPMSerializer_autogen.cpp",
        "src/dawn/fuzzers/lpmfuzz/DawnLPMSerializer_autogen.h",
        "src/dawn/fuzzers/lpmfuzz/DawnLPMConstants_autogen.h",
      ]
    }

    # Generate the `.proto` files
    dawn_json_lpm_generator("dawn_lpmfuzz_proto") {
      target = "dawn_lpmfuzz_proto"
      outputs = [
        "src/dawn/fuzzers/lpmfuzz/dawn_lpm_autogen.proto",
        "src/dawn/fuzzers/lpmfuzz/dawn_object_types_lpm_autogen.proto",
      ]
    }

    # Copy handwritten `.proto` file to build directory
    copy("copy_dawn_custom_lpm") {
      sources =
          [ "${dawn_root}/src/dawn/fuzzers/lpmfuzz/dawn_custom_lpm.proto" ]
      outputs = [ "$root_out_dir/gen/third_party/dawn/src/dawn/fuzzers/lpmfuzz/dawn_custom_lpm.proto" ]
    }

    # Generate the `.pb.h` and `.pb.cc` files
    proto_library("dawn_lpm_proto") {
      proto_in_dir = "$root_out_dir/gen"
      proto_out_dir = "//"
      sources = get_target_outputs(":dawn_lpmfuzz_proto")
      sources += get_target_outputs(":copy_dawn_custom_lpm")

      generate_python = false
      use_protobuf_full = true
      deps = [
        ":copy_dawn_custom_lpm",
        ":dawn_lpmfuzz_proto",
        "//third_party/protobuf:protobuf_full",
      ]
    }

    # Compile dawnlpm fuzzer with extensive tint coverage
    dawn_lpm_template("dawn_lpm_fuzzer_vulkan_backend_with_tint") {
      defines = [ "DAWNLPM_FUZZ_TINT=1" ]
      dawn_lpm_sources = get_target_outputs(":dawn_lpmfuzz_cpp")
      dawn_lpm_sources += [
        "lpmfuzz/DawnLPMFuzzer.cpp",
        "lpmfuzz/DawnLPMFuzzer.h",
        "lpmfuzz/DawnLPMFuzzerAndVulkanBackend.cpp",
        "lpmfuzz/DawnLPMObjectStore.cpp",
        "lpmfuzz/DawnLPMObjectStore.h",
        "lpmfuzz/DawnLPMSerializerCustom.cpp",
        "lpmfuzz/DawnLPMSerializerCustom.h",
      ]
    }

    # Compile dawnlpm api fuzzer
    dawn_lpm_template("dawn_lpm_fuzzer_vulkan_backend") {
      defines = [ "DAWNLPM_FUZZ_TINT=0" ]
      dawn_lpm_sources = get_target_outputs(":dawn_lpmfuzz_cpp")
      dawn_lpm_sources += [
        "lpmfuzz/DawnLPMFuzzer.cpp",
        "lpmfuzz/DawnLPMFuzzer.h",
        "lpmfuzz/DawnLPMFuzzerAndVulkanBackend.cpp",
        "lpmfuzz/DawnLPMObjectStore.cpp",
        "lpmfuzz/DawnLPMObjectStore.h",
        "lpmfuzz/DawnLPMSerializerCustom.cpp",
        "lpmfuzz/DawnLPMSerializerCustom.h",
      ]
    }
  }

  # A group target to build all the fuzzers
  group("fuzzers") {
    testonly = true
    deps = [
      ":dawn_wire_server_and_frontend_fuzzer",
      ":dawn_wire_server_and_vulkan_backend_fuzzer",
    ]

    if (is_win) {
      deps += [ ":dawn_wire_server_and_d3d12_backend_fuzzer" ]
    }
  }
}
