# Specify the name of each test (the Test will be appended where needed).
set(tests
  CifSymmetry
  BondOrdersCorpus
  Cjson
  Cml
  Compression
  Dcd
  FileFormatGuard
  FileFormatManager
  Gromacs
  Lammps
  Mdl
  Pdb
  Smiles
  SmilesParser
  Trr
  Turbomole
  Vasp
  Xyz
  )

if(USE_HDF5)
  list(APPEND tests Hdf5)
endif()

include_directories("${CMAKE_CURRENT_BINARY_DIR}"
	"${AvogadroLibs_BINARY_DIR}/avogadro/io")

set(AVOGADRO_DATA ${AVOGADRO_DATA_ROOT})

configure_file("${CMAKE_CURRENT_SOURCE_DIR}/iotests.h.in"
  "${CMAKE_CURRENT_BINARY_DIR}/iotests.h" @ONLY)

# Build up the source file names.
set(testSrcs "")
foreach(TestName ${tests})
  message(STATUS "Adding ${TestName} test.")
  string(TOLOWER ${TestName} testname)
  list(APPEND testSrcs ${testname}test.cpp)
endforeach()
message(STATUS "Test source files: ${testSrcs}")

# Add a single executable for all of our tests.
add_executable(AvogadroIOTests ${testSrcs})
target_link_libraries(AvogadroIOTests Avogadro::IO
  ${GTEST_BOTH_LIBRARIES} ${EXTRA_LINK_LIB})
# Helpers shared between the core and io bond order tests.
target_include_directories(AvogadroIOTests PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/..")

# Now add all of the tests, using the gtest_filter argument so that only those
# cases are run in each test invocation.
foreach(TestName ${tests})
  add_test(NAME "Io-${TestName}"
    COMMAND AvogadroIOTests "--gtest_filter=${TestName}Test.*")
endforeach()

if (DEFINED ENV{LIB_FUZZING_ENGINE})
  option(ENABLE_FUZZ "Enable fuzz testing." ON)
else()
  option(ENABLE_FUZZ "Enable fuzz testing." OFF)
endif()

if(ENABLE_FUZZ OR DEFINED ENV{LIB_FUZZING_ENGINE})
  # Each name here is a *file extension* that FileFormatManager maps to a
  # format supporting Read | String -- fuzztest.cpp passes it straight to
  # readString(). Adding an extension no format claims for reading silently
  # produces a target that does nothing, so check supportedOperations() first.
  # The lookup is case-sensitive, hence POSCAR and OUTCAR.
  set(fuzz
    cjson
    cml
    sdf
    pdb
    xyz
    tmol
    POSCAR
    OUTCAR
    dump
    gro
    trr
    dcd
  )
  foreach(fuzzName ${fuzz})
    add_executable(fuzz_${fuzzName} fuzztest.cpp)
    target_compile_definitions(fuzz_${fuzzName} PRIVATE -DFUZZ_INPUT_FORMAT="${fuzzName}")
    if(DEFINED ENV{LIB_FUZZING_ENGINE})
      target_link_libraries(fuzz_${fuzzName} PRIVATE Avogadro::IO $ENV{LIB_FUZZING_ENGINE})
    else()
      target_compile_options(fuzz_${fuzzName} PRIVATE ${AvogadroLibs_FUZZ_COMPILE_OPTIONS})
      target_link_options(fuzz_${fuzzName} PRIVATE ${AvogadroLibs_FUZZ_LINK_OPTIONS})
      target_link_libraries(fuzz_${fuzzName} PRIVATE Avogadro::IO ${AvogadroLibs_FUZZ_LINK_LIBS})
    endif()
  endforeach()

  # SmilesFormat is write-only, so the SMILES parser needs its own harness
  # rather than an entry in the list above.
  add_executable(fuzz_smiles fuzz-smilesparser.cpp)
  if(DEFINED ENV{LIB_FUZZING_ENGINE})
    target_link_libraries(fuzz_smiles PRIVATE Avogadro::IO $ENV{LIB_FUZZING_ENGINE})
  else()
    target_compile_options(fuzz_smiles PRIVATE ${AvogadroLibs_FUZZ_COMPILE_OPTIONS})
    target_link_options(fuzz_smiles PRIVATE ${AvogadroLibs_FUZZ_LINK_OPTIONS})
    target_link_libraries(fuzz_smiles PRIVATE Avogadro::IO ${AvogadroLibs_FUZZ_LINK_LIBS})
  endif()

  # The compression harnesses take raw bytes rather than a chemical format, so
  # they cannot use fuzztest.cpp either. Each name here is built from
  # fuzz-<name>.cpp into target fuzz_<name>, matching tests/qtgui.
  #   decompress         arbitrary bytes into the decoder, drained with
  #                      several access patterns including seeks
  #   compress-roundtrip our encoder feeding our decoder, asserting the data
  #                      survives unchanged
  set(compressionFuzz
    decompress
    compress-roundtrip
  )
  foreach(fuzzName ${compressionFuzz})
    add_executable(fuzz_${fuzzName} fuzz-${fuzzName}.cpp)
    if(DEFINED ENV{LIB_FUZZING_ENGINE})
      target_link_libraries(fuzz_${fuzzName}
        PRIVATE Avogadro::IO $ENV{LIB_FUZZING_ENGINE})
    else()
      target_compile_options(fuzz_${fuzzName} PRIVATE ${AvogadroLibs_FUZZ_COMPILE_OPTIONS})
      target_link_options(fuzz_${fuzzName} PRIVATE ${AvogadroLibs_FUZZ_LINK_OPTIONS})
      target_link_libraries(fuzz_${fuzzName} PRIVATE Avogadro::IO ${AvogadroLibs_FUZZ_LINK_LIBS})
    endif()
  endforeach()
endif()
