# Added for autogenerated headers and LuaJIT ones.
include_directories(${PROJECT_SOURCE_DIR}/src)
include_directories(${PROJECT_BINARY_DIR}/src)
include_directories(${PROJECT_SOURCE_DIR}/src/box)

# A special target with fuzzer and sanitizer flags.
add_library(fuzzer_config INTERFACE)

target_compile_options(
    fuzzer_config
    INTERFACE
        $<$<NOT:$<BOOL:${OSS_FUZZ}>>:
        -fsanitize=fuzzer
        -fsanitize-coverage=trace-cmp
        -fprofile-instr-generate
        -fcoverage-mapping
        -g
        >
        $<$<BOOL:${OSS_FUZZ}>:
        ${CXX}
        ${CXXFLAGS}
        >
)

# `-stdlib=libstdc++` is required by ICU on OSS Fuzz.
# `-lc++` is used by Centipede, so `-lc++` needs to come after
# centipede's lib.
target_link_libraries(
    fuzzer_config
    INTERFACE
        $<$<NOT:$<BOOL:${OSS_FUZZ}>>:
        -fsanitize=fuzzer
        -fsanitize-coverage=trace-cmp
        -fprofile-instr-generate
        -fcoverage-mapping
        -g
        -stdlib=libstdc++
        >
        $<$<BOOL:${OSS_FUZZ}>:
        $ENV{LIB_FUZZING_ENGINE}
        -lc++
        -stdlib=libstdc++
        >
)

set(FUZZ_TEST_TARGETS "")

function(create_fuzz_test)
  cmake_parse_arguments(
    FUZZ
    ""
    "PREFIX"
    "SOURCES;LIBRARIES"
    ${ARGN}
  )
  message(STATUS "Creating fuzz test ${FUZZ_PREFIX}_fuzzer")
  add_executable(${FUZZ_PREFIX}_fuzzer ${FUZZ_SOURCES})
  # Use PUBLIC to force 'fuzzer_config' for all dependent targets.
  target_link_libraries(${FUZZ_PREFIX}_fuzzer PUBLIC ${FUZZ_LIBRARIES})
  set(FUZZ_TEST_TARGETS ${FUZZ_TEST_TARGETS} ${FUZZ_PREFIX}_fuzzer PARENT_SCOPE)
endfunction()

create_fuzz_test(PREFIX csv
                 SOURCES csv_fuzzer.c
                 LIBRARIES csv fuzzer_config
)

create_fuzz_test(PREFIX uri
                 SOURCES uri_fuzzer.c
                 LIBRARIES uri fuzzer_config
)

create_fuzz_test(PREFIX http_parser
                 SOURCES http_parser_fuzzer.c
                 LIBRARIES http_parser fuzzer_config
)

create_fuzz_test(PREFIX swim_proto_member
                 SOURCES swim_proto_member_fuzzer.c
                 LIBRARIES swim fuzzer_config
)

create_fuzz_test(PREFIX swim_proto_meta
                 SOURCES swim_proto_meta_fuzzer.c
                 LIBRARIES swim fuzzer_config
)

create_fuzz_test(PREFIX datetime_parse_full
                 SOURCES datetime_parse_full_fuzzer.c
                 LIBRARIES core fuzzer_config
)

create_fuzz_test(PREFIX datetime_strptime
                 SOURCES datetime_strptime_fuzzer.cc
                 LIBRARIES core fuzzer_config
)

create_fuzz_test(PREFIX mp_datetime
                 SOURCES mp_datetime_fuzzer.c
                 LIBRARIES core fuzzer_config
)

# Building xrow library triggers building LuaJIT that doesn't support UBSan.
# See https://github.com/tarantool/tarantool/issues/8473.
if (NOT ENABLE_UB_SANITIZER)
  create_fuzz_test(PREFIX xrow_greeting_decode
                   SOURCES xrow_greeting_decode_fuzzer.c
                   LIBRARIES xrow fuzzer_config)

  create_fuzz_test(PREFIX xrow_decode_id
                   SOURCES xrow_decode_id_fuzzer.c
                   LIBRARIES xrow fuzzer_config)

  create_fuzz_test(PREFIX xrow_decode_auth
                   SOURCES xrow_decode_auth_fuzzer.c
                   LIBRARIES xrow fuzzer_config)

  create_fuzz_test(PREFIX xrow_decode_begin
                   SOURCES xrow_decode_begin_fuzzer.c
                   LIBRARIES xrow fuzzer_config)

  create_fuzz_test(PREFIX xrow_decode_call
                   SOURCES xrow_decode_call_fuzzer.c
                  LIBRARIES xrow fuzzer_config)

  create_fuzz_test(PREFIX xrow_decode_dml
                   SOURCES xrow_decode_dml_fuzzer.c
                   LIBRARIES xrow fuzzer_config)

  create_fuzz_test(PREFIX xrow_decode_raft
                   SOURCES xrow_decode_raft_fuzzer.c
                   LIBRARIES xrow fuzzer_config)

  create_fuzz_test(PREFIX xrow_decode_sql
                   SOURCES xrow_decode_sql_fuzzer.c
                   LIBRARIES xrow fuzzer_config)

  create_fuzz_test(PREFIX xrow_decode_watch
                   SOURCES xrow_decode_watch_fuzzer.c
                   LIBRARIES xrow fuzzer_config)

  create_fuzz_test(PREFIX xrow_header_decode
                   SOURCES xrow_header_decode_fuzzer.c
                   LIBRARIES xrow fuzzer_config)

  create_fuzz_test(PREFIX xrow_decode_error
                   SOURCES xrow_decode_error_fuzzer.c
                   LIBRARIES xrow fuzzer_config)
endif ()

# Blocked by https://github.com/tarantool/tarantool/issues/8948.
if (NOT ENABLE_UB_SANITIZER)
  create_fuzz_test(PREFIX decimal_to_int64
                   SOURCES decimal_to_int64_fuzzer.c
                   LIBRARIES core fuzzer_config)
endif ()

include(ProtobufMutator)

# UndefinedBehaviorSanitizer is not supported in LuaJIT.
# See https://github.com/tarantool/tarantool/issues/8473
if (NOT ENABLE_UB_SANITIZER)
    add_subdirectory(luaL_loadbuffer)
endif()

add_custom_target(fuzzers
                  DEPENDS ${FUZZ_TEST_TARGETS}
                  COMMENT "Build fuzzers")
