# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//build/config/compiler/compiler.gni")
import("//mojo/features.gni")
import("//testing/libfuzzer/fuzzer_test.gni")
import("//testing/test.gni")

if (is_mac) {
  import("//third_party/protobuf/proto_library.gni")
}

component("embedder_internal") {
  output_name = "mojo_core_embedder_internal"
  public_deps = [ ":impl_for_embedder" ]
  visibility = [
    ":driver_for_ipcz_tests",
    ":test_sources",
    "//mojo:*",
    "//mojo/core/embedder",
    "//mojo/core/test:test_support",
  ]
}

# Bits of the EDK library which do not depend on public API linkage. It is
# not allowed for this target or any of its transitive dependencies to depend
# on anything under //mojo/public beyond strict C type definitions.
source_set("impl_for_embedder") {
  visibility = [
    ":core_impl_for_fuzzers",
    ":embedder_internal",
  ]

  public = [
    "channel.h",
    "configuration.h",
    "connection_params.h",
    "core_ipcz.h",
    "embedder/configuration.h",
    "embedder/process_error_callback.h",
    "fuzzing_utils.h",
    "handle_signals_state.h",
    "ipcz_api.h",
    "ipcz_driver/base_shared_memory_service.h",
    "ipcz_driver/driver.h",
    "ipcz_driver/envelope.h",
    "ipcz_driver/invitation.h",
    "ipcz_driver/mojo_message.h",
    "ipcz_driver/object.h",
    "ipcz_driver/ring_buffer.h",
    "ipcz_driver/shared_buffer.h",
    "ipcz_driver/shared_buffer_mapping.h",
    "ipcz_driver/transmissible_platform_handle.h",
    "ipcz_driver/transport.h",
    "ipcz_driver/wrapped_platform_handle.h",
    "platform_handle_utils.h",
    "scoped_ipcz_handle.h",
  ]

  sources = [
    "broker.h",
    "channel.cc",
    "configuration.cc",
    "connection_params.cc",
    "core_ipcz.cc",
    "fuzzing_utils.cc",
    "ipcz_api.cc",
    "ipcz_driver/base_shared_memory_service.cc",
    "ipcz_driver/data_pipe.cc",
    "ipcz_driver/data_pipe.h",
    "ipcz_driver/driver.cc",
    "ipcz_driver/envelope.cc",
    "ipcz_driver/invitation.cc",
    "ipcz_driver/mojo_message.cc",
    "ipcz_driver/mojo_trap.cc",
    "ipcz_driver/mojo_trap.h",
    "ipcz_driver/object.cc",
    "ipcz_driver/ring_buffer.cc",
    "ipcz_driver/shared_buffer.cc",
    "ipcz_driver/shared_buffer_mapping.cc",
    "ipcz_driver/transmissible_platform_handle.cc",
    "ipcz_driver/transport.cc",
    "ipcz_driver/validate_enum.h",
    "ipcz_driver/wrapped_platform_handle.cc",
    "platform_handle_in_transit.cc",
    "platform_handle_in_transit.h",
    "platform_handle_utils.cc",
    "scoped_ipcz_handle.cc",
  ]

  public_deps = [
    "//base",
    "//mojo:buildflags",
    "//mojo/core/embedder:features",
    "//mojo/public/c/system:headers",
    "//mojo/public/cpp/bindings:mojo_buildflags",
    "//mojo/public/cpp/platform",
    "//third_party/abseil-cpp:absl",
    "//third_party/ipcz/src:ipcz",
  ]

  if (is_fuchsia) {
    sources += [ "channel_fuchsia.cc" ]

    public_deps += [ "//third_party/fuchsia-sdk/sdk/pkg/fdio" ]
  }

  if (is_posix && !mojo_use_apple_channel) {
    sources += [
      "broker_posix.cc",
      "channel_posix.cc",
      "channel_posix.h",
    ]

    if (is_linux || is_chromeos || is_android) {
      sources += [
        "channel_linux.cc",
        "channel_linux.h",
      ]

      public += [ "channel_linux.h" ]
    }
  }

  if (mojo_use_apple_channel) {
    sources += [ "channel_mac.cc" ]
  }

  sources += [
    "broker_host.cc",
    "broker_host.h",
  ]

  configs += [ "//build/config/compiler:wexit_time_destructors" ]

  defines = [ "MOJO_SYSTEM_IMPL_IMPLEMENTATION" ]
  deps = [ "//crypto" ]

  if (is_win) {
    sources += [
      "broker_win.cc",
      "channel_win.cc",
    ]
  }

  if (!is_debug && !optimize_for_size) {
    configs -= [ "//build/config/compiler:default_optimization" ]
    configs += [ "//build/config/compiler:optimize_max" ]
  }
}

source_set("driver_for_ipcz_tests") {
  testonly = true
  sources = [ "ipcz_driver/driver_for_ipcz_tests.cc" ]
  deps = [
    ":embedder_internal",
    "//base",
    "//base/test:test_support",
    "//third_party/ipcz/src:ipcz_test_support",
  ]
}

source_set("test_sources") {
  testonly = true
  sources = [
    "channel_unittest.cc",
    "core_ipcz_test.cc",
    "embedder_unittest.cc",
    "message_pipe_unittest.cc",
    "message_unittest.cc",
    "platform_wrapper_unittest.cc",
    "shared_buffer_unittest.cc",
    "signals_unittest.cc",
    "trap_unittest.cc",
  ]

  if (use_blink) {
    sources += [
      "data_pipe_unittest.cc",
      "invitation_unittest.cc",
      "ipcz_driver/ring_buffer_test.cc",
      "ipcz_driver/transport_test.cc",
      "multiprocess_message_pipe_unittest.cc",
    ]
  }

  deps = [
    "//base",
    "//base/test:test_support",
    "//build:blink_buildflags",
    "//build:chromeos_buildflags",
    "//mojo:buildflags",
    "//mojo/core:embedder_internal",
    "//mojo/core/embedder",
    "//mojo/core/test:run_all_unittests",
    "//mojo/core/test:test_support",
    "//mojo/public/cpp/system",
    "//testing/gmock",
    "//testing/gtest",
    "//third_party/ipcz/src:ipcz",
  ]

  # TODO(crbug.com/40031409): Fix code that adds exit-time destructors and
  # enable the diagnostic by removing this line.
  configs += [ "//build/config/compiler:no_exit_time_destructors" ]
}

group("core_impl_for_fuzzers") {
  public_deps = [ ":impl_for_embedder" ]
}

if (is_mac) {
  protoc_convert("mojo_core_channel_mac_fuzzer_convert_corpus") {
    sources = [
      "test/data/channel_mac/bad_handshake1.textproto",
      "test/data/channel_mac/bad_handshake2.textproto",
      "test/data/channel_mac/bad_handshake3.textproto",
      "test/data/channel_mac/bad_message1.textproto",
      "test/data/channel_mac/complex_messages.textproto",
      "test/data/channel_mac/double_handshake.textproto",
      "test/data/channel_mac/handshake.textproto",
      "test/data/channel_mac/invalid_handles.textproto",
      "test/data/channel_mac/non_complex_with_descriptor_count.textproto",
      "test/data/channel_mac/ool_type_mismatch.textproto",
      "test/data/channel_mac/simple_message1.textproto",
      "test/data/channel_mac/simple_message2.textproto",
    ]

    inputs = [
      "test/data/channel_mac/channel_mac.proto",
      "//testing/libfuzzer/fuzzers/mach/mach_message.proto",
    ]

    output_pattern = "$target_gen_dir/mojo_core_channel_mac_corpus/{{source_name_part}}.binarypb"

    args = [
      "--encode=mojo_fuzzer.ChannelMac",
      "-I",
      rebase_path("//", root_build_dir),
      "mojo/core/test/data/channel_mac/channel_mac.proto",
    ]
  }
}

fuzzer_test("mojo_core_ipcz_channel_fuzzer") {
  sources = [ "ipcz_channel_fuzzer.cc" ]
  deps = [
    ":core_impl_for_fuzzers",
    "//base",
    "//mojo/public/cpp/platform",
    "//testing/libfuzzer:libfuzzer_base_wrappers",
  ]
}
