include(AwsLibFuzzer)
include(AwsTestHarness)
enable_testing()

file(GLOB META_TEST_SRC "assert_test.c")
file(GLOB TEST_SRC "*.c")
list(REMOVE_ITEM TEST_SRC ${META_TEST_SRC})
file(GLOB TEST_HDRS "*.h")
file(GLOB TESTS ${TEST_HDRS} ${TEST_SRC})

set(METATEST_BINARY_NAME ${CMAKE_PROJECT_NAME}-assert-tests)

add_executable(${METATEST_BINARY_NAME} ${META_TEST_SRC})
aws_set_common_properties(${METATEST_BINARY_NAME} NO_WEXTRA NO_PEDANTIC)
aws_add_sanitizers(${METATEST_BINARY_NAME} ${${CMAKE_PROJECT_NAME}_SANITIZERS})
target_link_libraries(${METATEST_BINARY_NAME} PRIVATE ${CMAKE_PROJECT_NAME})

target_compile_definitions(${METATEST_BINARY_NAME} PRIVATE AWS_UNSTABLE_TESTING_API=1)
target_include_directories(${METATEST_BINARY_NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR})
if(MSVC)
    target_compile_definitions(${METATEST_BINARY_NAME} PRIVATE "-D_CRT_SECURE_NO_WARNINGS")
endif()

add_test(assert_test ${METATEST_BINARY_NAME} ${CMAKE_CURRENT_BINARY_DIR}/metatest.tmp)

add_test_case(raise_errors_test)
add_test_case(reset_errors_test)
add_test_case(error_callback_test)
add_test_case(unknown_error_code_in_slot_test)
add_test_case(unknown_error_code_no_slot_test)
add_test_case(unknown_error_code_range_too_large_test)

add_test_case(thread_creation_join_test)

add_test_case(mutex_aquire_release_test)
add_test_case(mutex_is_actually_mutex_test)

add_test_case(conditional_notify_one)
add_test_case(conditional_notify_all)

add_test_case(error_code_cross_thread_test)

add_test_case(high_res_clock_increments_test)
add_test_case(sys_clock_increments_test)
add_test_case(test_sec_and_millis_conversions)
add_test_case(test_sec_and_micros_conversions)
add_test_case(test_sec_and_nanos_conversions)
add_test_case(test_milli_and_micros_conversion)
add_test_case(test_milli_and_nanos_conversion)
add_test_case(test_micro_and_nanos_conversion)
add_test_case(test_precision_loss_remainders_conversion)
add_test_case(test_overflow_conversion)

add_test_case(array_list_order_push_back_pop_front_test)
add_test_case(array_list_order_push_back_pop_back_test)
add_test_case(array_list_pop_front_n_test)
add_test_case(array_list_exponential_mem_model_test)
add_test_case(array_list_exponential_mem_model_iteration_test)
add_test_case(array_list_set_at_overwrite_safety)
add_test_case(array_list_iteration_by_ptr_test)
add_test_case(array_list_iteration_test)
add_test_case(array_list_preallocated_iteration_test)
add_test_case(array_list_preallocated_push_test)
add_test_case(array_list_shrink_to_fit_test)
add_test_case(array_list_shrink_to_fit_static_test)
add_test_case(array_list_clear_test)
add_test_case(array_list_copy_test)
add_test_case(array_list_swap_contents_test)
add_test_case(array_list_not_enough_space_test)
add_test_case(array_list_not_enough_space_test_failure)
add_test_case(array_list_of_strings_sort)
add_test_case(array_list_empty_sort)
add_test_case(priority_queue_push_pop_order_test)
add_test_case(priority_queue_random_values_test)
add_test_case(priority_queue_size_and_capacity_test)
add_test_case(priority_queue_remove_root_test)
add_test_case(priority_queue_remove_leaf_test)
add_test_case(priority_queue_remove_interior_sift_up_test)
add_test_case(priority_queue_remove_interior_sift_down_test)

add_test_case(linked_list_push_back_pop_front)
add_test_case(linked_list_push_front_pop_back)
add_test_case(linked_list_iteration)
add_test_case(linked_list_swap_contents)

add_test_case(hex_encoding_test_case_empty_test)
add_test_case(hex_encoding_test_case_f_test)
add_test_case(hex_encoding_test_case_fo_test)
add_test_case(hex_encoding_test_case_foo_test)
add_test_case(hex_encoding_test_case_foob_test)
add_test_case(hex_encoding_test_case_fooba_test)
add_test_case(hex_encoding_test_case_foobar_test)
add_test_case(hex_encoding_test_case_missing_leading_zero)
add_test_case(hex_encoding_invalid_buffer_size_test)
add_test_case(hex_encoding_highbyte_string_test)
add_test_case(hex_encoding_overflow_test)
add_test_case(hex_encoding_invalid_string_test)
add_test_case(base64_encoding_test_case_empty_test)
add_test_case(base64_encoding_test_case_f_test)
add_test_case(base64_encoding_test_case_fo_test)
add_test_case(base64_encoding_test_case_foo_test)
add_test_case(base64_encoding_test_case_foob_test)
add_test_case(base64_encoding_test_case_fooba_test)
add_test_case(base64_encoding_test_case_foobar_test)
add_test_case(base64_encoding_test_case_32bytes_test)
add_test_case(base64_encoding_buffer_size_too_small_test)
add_test_case(base64_encoding_buffer_size_overflow_test)
add_test_case(base64_encoding_buffer_size_invalid_test)
add_test_case(base64_encoding_invalid_buffer_test)
add_test_case(base64_encoding_highbyte_string_test)
add_test_case(base64_encoding_invalid_padding_test)
add_test_case(base64_encoding_test_zeros)
add_test_case(base64_encoding_test_roundtrip)
add_test_case(base64_encoding_test_all_values)
add_test_case(uint64_buffer_test)
add_test_case(uint64_buffer_non_aligned_test)
add_test_case(uint32_buffer_test)
add_test_case(uint32_buffer_non_aligned_test)
add_test_case(uint24_buffer_test)
add_test_case(uint24_buffer_non_aligned_test)
add_test_case(uint16_buffer_test)
add_test_case(uint16_buffer_non_aligned_test)
add_test_case(uint16_buffer_signed_positive_test)
add_test_case(uint16_buffer_signed_negative_test)

add_test_case(scheduler_cleanup_cancellation)
add_test_case(scheduler_ordering_test)
add_test_case(scheduler_pops_task_late_test)
add_test_case(scheduler_has_tasks_test)
add_test_case(scheduler_reentrant_safe)
add_test_case(scheduler_cleanup_reentrants)
add_test_case(scheduler_oom_still_works)
add_test_case(scheduler_schedule_cancellation)

add_test_case(test_hash_table_create_find)
add_test_case(test_hash_table_string_create_find)
add_test_case(test_hash_table_put)
add_test_case(test_hash_table_put_null_dtor)
add_test_case(test_hash_table_swap_move)
add_test_case(test_hash_table_string_clean_up)
add_test_case(test_hash_table_hash_collision)
add_test_case(test_hash_table_hash_overwrite)
add_test_case(test_hash_table_hash_remove)
add_test_case(test_hash_table_hash_clear_allows_cleanup)
add_test_case(test_hash_table_on_resize_returns_correct_entry)
add_test_case(test_hash_table_foreach)
add_test_case(test_hash_table_iter)
add_test_case(test_hash_table_empty_iter)
add_test_case(test_hash_table_iter_detail)
add_test_case(test_hash_table_eq)
add_test_case(test_hash_churn)
add_test_case(test_hash_table_cleanup_idempotent)
add_test_case(test_hash_table_byte_cursor_create_find)

add_test_case(test_mul_size_checked)
add_test_case(test_mul_size_saturating)
add_test_case(test_mul_u32_checked)
add_test_case(test_mul_u32_saturating)
add_test_case(test_mul_u64_checked)
add_test_case(test_mul_u64_saturating)
add_test_case(test_add_size_checked)
add_test_case(test_add_size_saturating)
add_test_case(test_add_u32_checked)
add_test_case(test_add_u32_saturating)
add_test_case(test_add_u64_checked)
add_test_case(test_add_u64_saturating)

add_test_case(nospec_index_test)
add_test_case(test_byte_cursor_advance)
add_test_case(test_byte_cursor_advance_nospec)

add_test_case(byte_cursor_write_tests)
add_test_case(byte_cursor_read_tests)
add_test_case(byte_cursor_limit_tests)
add_test_case(test_byte_cursor_right_trim_empty)
add_test_case(test_byte_cursor_right_trim_all_whitespace)
add_test_case(test_byte_cursor_right_trim_basic)
add_test_case(test_byte_cursor_left_trim_empty)
add_test_case(test_byte_cursor_left_trim_all_whitespace)
add_test_case(test_byte_cursor_left_trim_basic)
add_test_case(test_byte_cursor_trim_basic)

add_test_case(string_tests)
add_test_case(binary_string_test)
add_test_case(string_compare_test)
add_test_case(string_destroy_secure_test)

add_test_case(test_char_split_happy_path)
add_test_case(test_char_split_ends_with_token)
add_test_case(test_char_split_token_not_present)
add_test_case(test_char_split_empty)
add_test_case(test_char_split_adj_tokens)
add_test_case(test_char_split_begins_with_token)
add_test_case(test_char_split_with_max_splits)
add_test_case(test_char_split_output_too_small)
add_test_case(test_buffer_cat)
add_test_case(test_buffer_cat_dest_too_small)
add_test_case(test_buffer_cpy)
add_test_case(test_buffer_cpy_dest_too_small)
add_test_case(test_buffer_cpy_offsets)
add_test_case(test_buffer_cpy_offsets_dest_too_small)
add_test_case(test_buffer_eq)
add_test_case(test_buffer_eq_same_content_different_len)
add_test_case(test_buffer_eq_null_byte_buffer)
add_test_case(test_buffer_eq_null_internal_byte_buffer)
add_test_case(test_buffer_init_copy)
add_test_case(test_buffer_init_copy_null_buffer)
add_test_case(test_buffer_advance)

add_test_case(byte_swap_test)

add_test_case(test_cpu_count_at_least_works_superficially)

add_test_case(test_realloc_fallback)
add_test_case(test_realloc_fallback_oom)
add_test_case(test_realloc_passthrough)
add_test_case(test_realloc_passthrough_oom)
add_test_case(test_cf_allocator_wrapper)
add_test_case(test_acquire_many)

add_test_case(test_lru_cache_overflow_static_members)
add_test_case(test_lru_cache_lru_ness_static_members)
add_test_case(test_lru_cache_entries_cleanup)
add_test_case(test_lru_cache_overwrite)
add_test_case(test_lru_cache_element_access_members)

add_test_case(rw_lock_aquire_release_test)
add_test_case(rw_lock_is_actually_rw_lock_test)
add_test_case(rw_lock_many_readers_test)
add_test_case(test_secure_zero)
add_test_case(test_buffer_secure_zero)
add_test_case(test_buffer_clean_up_secure)

add_test_case(atomics_semantics)
add_test_case(atomics_semantics_implicit)
add_test_case(atomics_static_init)
add_test_case(atomics_loads_reordered_with_older_stores)
add_test_case(atomics_acquire_to_release_one_direction)
add_test_case(atomics_acquire_to_release_mixed)

add_test_case(rfc822_utc_parsing)
add_test_case(rfc822_utc_parsing_auto_detect)
add_test_case(rfc822_local_time_east_of_gmt_parsing)
add_test_case(rfc822_local_time_west_of_gmt_parsing)
add_test_case(rfc822_utc_two_digit_year_parsing)
add_test_case(rfc822_utc_no_dow_parsing)
add_test_case(rfc822_utc_dos_prevented)
add_test_case(rfc822_invalid_format)
add_test_case(rfc822_invalid_tz)
add_test_case(rfc822_invalid_auto_format)
add_test_case(iso8601_utc_parsing)
add_test_case(iso8601_utc_parsing_auto_detect)
add_test_case(iso8601_date_only_parsing)
add_test_case(iso8601_utc_no_colon_parsing)
add_test_case(iso8601_utc_dos_prevented)
add_test_case(iso8601_invalid_format)
add_test_case(iso8601_invalid_auto_format)
add_test_case(unix_epoch_parsing)
add_test_case(millis_parsing)

add_test_case(device_rand_u64)
add_test_case(device_rand_u32)
add_test_case(device_rand_u16)
add_test_case(device_rand_buffer)

add_test_case(uuid_string)
add_test_case(prefilled_uuid_string)
add_test_case(uuid_string_short_buffer)
add_test_case(uuid_string_parse)
add_test_case(uuid_string_parse_too_short)
add_test_case(uuid_string_parse_malformed)

add_test_case(test_environment_functions)

add_test_case(short_argument_parse)
add_test_case(long_argument_parse)
add_test_case(unqualified_argument_parse)
add_test_case(unknown_argument_parse)

generate_test_driver(${CMAKE_PROJECT_NAME}-tests)

if (NOT MSVC)
    #we have some tests here that purposely overflow
    target_compile_options(${CMAKE_PROJECT_NAME}-tests PRIVATE -Wno-overflow)
endif()

file(GLOB FUZZ_TESTS "fuzz/*.c")
aws_add_fuzz_tests("${FUZZ_TESTS}" "")
