include(AwsTestHarness)
enable_testing()
include(CTest)

file(GLOB TEST_SRC "*.cpp")
file(GLOB TEST_HDRS "*.h")
file(GLOB TESTS ${TEST_HDRS} ${TEST_SRC})

set(TEST_BINARY_NAME ${PROJECT_NAME}-tests)

add_test_case(ApiMultiCreateDestroy)
add_test_case(ApiMultiDefaultCreateDestroy)
add_test_case(ApiStaticDefaultCreateDestroy)
add_test_case(EventLoopResourceSafety)
add_test_case(ClientBootstrapResourceSafety)

if(NOT BYO_CRYPTO)
    add_net_test_case(MqttClientResourceSafety)
    add_net_test_case(MqttClientNewConnectionUninitializedTlsContext)
    add_net_test_case(TLSContextResourceSafety)
    add_net_test_case(TLSContextUninitializedNewConnectionOptions)
    add_test_case(Sigv4aSigningTestCredentials)

    add_net_test_case(IoTMqtt311ConnectWithNoSigningCustomAuth)
    add_net_test_case(IoTMqtt311ConnectWithSigningCustomAuth)
    add_net_test_case(IoTMqtt311ConnectWithSigningCustomAuthUnencoded)
    add_net_test_case(IoTMqtt311ConnectWithSigningCustomAuthWebsockets)
    add_net_test_case(IoTMqtt311ConnectWithSigningCustomAuthWebsocketsUnencoded)
    add_net_test_case(IoTMqtt311ConnectWithPKCS11)
    add_net_test_case(IoTMqtt311ConnectWithPKCS12)
    add_net_test_case(IoTMqtt311ConnectWithWindowsCert)
    add_net_test_case(IoTMqtt311ConnectWSDefault)
    add_net_test_case(IoTMqtt311ConnectWSStatic)
    add_net_test_case(IoTMqtt311ConnectWSCognito)
    add_net_test_case(IoTMqtt311ConnectWSProfile)
    add_net_test_case(IoTMqtt311ConnectWSEnvironment)

    add_net_test_case(IoTMqtt5ConnectWithmTLS)
    add_net_test_case(IoTMqtt5ConnectWithWebsocket)
    add_net_test_case(IoTMqtt5ConnectWithSigningCustomAuth)
    add_net_test_case(IoTMqtt5ConnectWithSigningCustomAuthUnencoded)
    add_net_test_case(IoTMqtt5ConnectWithNoSigningCustomAuth)
    add_net_test_case(IoTMqtt5ConnectWithNoSigningCustomAuthWebsockets)
    add_net_test_case(IoTMqtt5ConnectWithSigningCustomAuthWebsockets)
    add_net_test_case(IoTMqtt5ConnectWithSigningCustomAuthWebsocketsUnencoded)
    add_net_test_case(IoTMqtt5ConnectWithPKCS11)
    add_net_test_case(IoTMqtt5ConnectWithPKCS12)
    add_net_test_case(IoTMqtt5ConnectWithWindowsCert)
    add_net_test_case(IoTMqtt5ConnectWSStatic)
    add_net_test_case(IoTMqtt5ConnectWSCognito)
    add_net_test_case(IoTMqtt5ConnectWSProfile)
    add_net_test_case(IoTMqtt5ConnectWSEnvironment)
    add_net_test_case(IoTMqtt5ConnectWSX509)

endif()

add_test_case(Base64RoundTrip)
add_test_case(DateTimeBinding)
add_test_case(BasicJsonParsing)
add_test_case(JsonNullParsing)
add_test_case(JsonNullNestedObject)
add_test_case(JsonExplicitNull)
add_test_case(JsonBoolTest)
add_test_case(JsonMoveTest)
add_test_case(SHA256ResourceSafety)
add_test_case(MD5ResourceSafety)
add_test_case(SHA1ResourceSafety)
add_test_case(SHA256HMACResourceSafety)

# TODO: disable aes byo tests for now. c-cal side is missing ability to override
# aes constructors. those need to be implemented first before we can support it.
if(NOT BYO_CRYPTO)
    add_test_case(AES_256_CBC_Generated_Materials_ResourceSafety)
    add_test_case(AES_256_CTR_Generated_Materials_ResourceSafety)
    add_test_case(AES_256_GCM_Generated_Materials_ResourceSafety)
    add_test_case(AES_256_Keywrap_Generated_Materials_ResourceSafety)
endif()

if(NOT BYO_CRYPTO)
    add_net_test_case(HttpDownloadNoBackPressureHTTP1_1)
    add_net_test_case(HttpDownloadNoBackPressureHTTP2)
    add_net_test_case(HttpStreamUnActivated)
    add_net_test_case(HttpCreateConnectionInvalidTlsConnectionOptions)
    add_net_test_case(IotPublishSubscribe)
    add_net_test_case(IotConnectionSuccessTest)
    add_net_test_case(IotConnectionFailureTest)
    add_net_test_case(IotWillTest)
    add_net_test_case(IoTStatisticsPublishWaitStatisticsDisconnect)
    add_net_test_case(IoTStatisticsPublishStatisticsWaitDisconnect)
    add_net_test_case(HttpClientConnectionManagerResourceSafety)
    add_net_test_case(HttpClientConnectionManagerInvalidTlsConnectionOptions)
    add_net_test_case(HttpClientConnectionWithPendingAcquisitions)
    add_net_test_case(HttpClientConnectionWithPendingAcquisitionsAndClosedConnections)
    add_net_test_case(IotConnectionDestruction)
    add_net_test_case(IotConnectionDestructionWithExecutingCallback)
    add_net_test_case(IotConnectionDestructionWithinConnectionCallback)
    add_net_test_case(IotConnectionDestructionWithinDisconnectCallback)
    add_net_test_case(IotConnectionDestructionWithPublish)
endif()

add_test_case(DefaultResolution)
add_test_case(OptionalCopySafety)
add_test_case(OptionalMoveSafety)
add_test_case(OptionalEmplace)
add_test_case(OptionalCopyAndMoveSemantics)
add_test_case(VariantCompiles)
add_test_case(VariantConstructor)
add_test_case(VariantAssignmentOperator)
add_test_case(VariantWithMoveOnlyUnderlyingType)
add_test_case(VariantWithCopyOnlyUnderlyingType)
add_test_case(VariantWithNoDefaultConstructibleUnderlyingType)
add_test_case(VariantExceptionSafety_DefaultConstructor)
add_test_case(VariantExceptionSafety_MoveConstructor)
add_test_case(VariantExceptionSafety_CopyConstructor)
add_test_case(VariantEmplace)
add_test_case(VariantVisitor)
add_test_case(StreamTestCreateDestroyWrapper)
add_test_case(StreamTestLength)
add_test_case(StreamTestRead)
add_test_case(StreamTestReadEmpty)
add_test_case(StreamTestSeekBegin)
add_test_case(StreamTestSeekEnd)
add_test_case(StreamTestRefcount)
add_test_case(TestCredentialsConstruction)
add_test_case(TestCredentialsConstructionWithAccountId)
add_test_case(TestAnonymousCredentialsConstruction)
add_test_case(TestProviderStaticGet)
add_test_case(TestProviderAnonymousGet)
add_test_case(TestProviderEnvironmentGet)
add_test_case(TestProviderProfileGet)
add_test_case(TestProviderImdsGet)

if(NOT BYO_CRYPTO)
    add_net_test_case(TestProviderDefaultChainGet)
    add_net_test_case(TestProviderDefaultChainManualTlsContextGet)
    add_test_case(STSWebIdentityCredentialsProviderFailureTest)
endif()

add_test_case(TestProviderDelegateGet)
add_test_case(TestProviderDelegateGetAnonymous)
add_test_case(HttpRequestTestCreateDestroy)
add_test_case(Sigv4SigningTestCreateDestroy)

if(NOT BYO_CRYPTO)
    add_test_case(Sigv4SigningTestSimple)
    add_test_case(Sigv4SigningTestCredentials)
    add_test_case(Sigv4SigningTestUnsignedPayload)
endif()

add_test_case(UUIDToString)
add_test_case(TestIntArrayListToVector)
add_test_case(TestByteCursorArrayListToVector)
add_test_case(StringViewTest)
add_test_case(TestCreatingImdsClient)
add_test_case(ChannelHandlerInterop)

if(AWS_BUILDING_ON_EC2)
    add_test_case(TestImdsClientGetInstanceInfo)
    add_test_case(TestImdsClientGetCredentials)
endif()

if(ENABLE_PROXY_INTEGRATION_TESTS AND NOT BYO_CRYPTO)
    # connection manager proxy tests
    add_test_case(ConnectionManagerTunnelingProxyHttp)
    add_test_case(ConnectionManagerTunnelingProxyHttps)
    add_test_case(ConnectionManagerTunnelingProxyHttpsInvalidTlsOptions)
    add_test_case(ConnectionManagerForwardingProxy)
    add_test_case(ConnectionManagerTunnelingProxyBasicAuthDeprecated)
    add_test_case(ConnectionManagerTunnelingProxyBasicAuth)

    # direction connection proxy tests
    add_test_case(DirectConnectionTunnelingProxyHttp)
    add_test_case(DirectConnectionTunnelingProxyHttps)
    add_test_case(DirectConnectionTunnelingProxyHttpsInvalidTlsOptions)
    add_test_case(DirectConnectionForwardingProxy)
    add_test_case(DirectConnectionTunnelingProxyBasicAuthDeprecated)
    add_test_case(DirectConnectionTunnelingProxyBasicAuth)

    # x509 provider proxy tests
    add_test_case(X509ProxyHttpGetCredentials)
    add_test_case(X509ProxyHttpsGetCredentials)
    add_test_case(X509ProxyBasicAuthDeprecatedGetCredentials)
    add_test_case(X509ProxyBasicAuthGetCredentials)

    # mqtt-over-websockets proxy tests using x509 credentials
    add_test_case(MqttOverWebsocketsViaHttpProxy)
    add_test_case(MqttOverWebsocketsViaHttpsProxy)
    add_test_case(MqttOverWebsocketsViaHttpProxyBasicAuthDeprecated)
    add_test_case(MqttOverWebsocketsViaHttpProxyBasicAuth)

    # mqtt-via-alpn proxy tests
    add_test_case(MqttViaHttpProxyAlpn)
    add_test_case(MqttViaHttpsProxyAlpn)
    add_test_case(MqttViaHttpProxyAlpnBasicAuthDeprecated)
    add_test_case(MqttViaHttpProxyAlpnBasicAuth)
endif()

#MQTT311 related tests
if (NOT BYO_CRYPTO)
    # MQTT311 TESTS
    add_net_test_case(Mqtt311DirectConnectionMinimal)
    add_net_test_case(Mqtt311DirectConnectionWithBasicAuth)
    add_net_test_case(Mqtt311DirectConnectionWithTLS)
    add_net_test_case(Mqtt311DirectConnectionWithMutualTLS)
    add_net_test_case(Mqtt311DirectConnectionWithHttpProxy)
    add_net_test_case(Mqtt311WSConnectionMinimal)
    add_net_test_case(Mqtt311WSConnectionWithBasicAuth)
    add_net_test_case(Mqtt311WSConnectionWithTLS)
    add_net_test_case(Mqtt311WSConnectionWithHttpProxy)
endif()

#MQTT5 related tests
add_test_case(Mqtt5NewClientMinimal)
add_test_case(Mqtt5NewClientFull)
if(NOT BYO_CRYPTO)
    # MQTT5 TESTS
    add_net_test_case(Mqtt5DirectConnectionMinimal)
    add_net_test_case(Mqtt5DirectConnectionWithBasicAuth)
    add_net_test_case(Mqtt5DirectConnectionWithTLS)
    add_net_test_case(Mqtt5DirectConnectionWithMutualTLS)
    add_net_test_case(Mqtt5DirectConnectionWithHttpProxy)
    add_net_test_case(Mqtt5DirectConnectionFull)
    add_net_test_case(Mqtt5WSConnectionMinimal)
    add_net_test_case(Mqtt5WSConnectionWithBasicAuth)
    add_net_test_case(Mqtt5WSConnectionWithTLS)
    add_net_test_case(Mqtt5WSConnectionWithMutualTLS)
    # Skip the websocket connection with http proxy
    # add_net_test_case(Mqtt5WSConnectionWithHttpProxy)
    add_net_test_case(Mqtt5WSConnectionFull)
    add_net_test_case(Mqtt5InvalidHostname)
    add_net_test_case(Mqtt5InvalidPort)
    add_net_test_case(Mqtt5WSInvalidPort)
    add_net_test_case(Mqtt5SocketTimeout)
    add_net_test_case(Mqtt5IncorrectBasicAuth)
    add_net_test_case(Mqtt5IncorrectWSConnect)
    add_net_test_case(Mqtt5DoubleClientIDFailure)
    add_net_test_case(Mqtt5NegotiatedSettingsHappy)
    add_net_test_case(Mqtt5NegotiatedSettingsFull)
    add_net_test_case(Mqtt5NegotiatedSettingsLimit)
    add_net_test_case(Mqtt5NegotiatedSettingsRejoinAlways)
    add_net_test_case(Mqtt5SubUnsub)
    add_net_test_case(Mqtt5WillTest)
    add_net_test_case(Mqtt5NullPublish)
    add_net_test_case(Mqtt5NullSubscribe)
    add_net_test_case(Mqtt5NullUnsubscribe)
    add_net_test_case(Mqtt5ReuseUnsubscribePacket)
    add_net_test_case(Mqtt5QoS1SubPub)
    add_net_test_case(Mqtt5RetainSetAndClear)

    # IOT CORE TEST
    add_net_test_case(Mqtt5InterruptSub)
    add_net_test_case(Mqtt5InterruptUnsub)
    add_net_test_case(Mqtt5InterruptPublishQoS1)
    add_net_test_case(Mqtt5OperationStatisticsSimple)
    add_net_test_case(Mqtt5SharedSubscriptionTest)

    # Mqtt5-to-3 Adapter
    add_test_case(Mqtt5to3AdapterNewConnectionMin)
    add_test_case(Mqtt5to3AdapterNewClientFull)
    add_net_test_case(Mqtt5to3AdapterDirectConnectionMinimalThroughMqtt3)
    add_net_test_case(Mqtt5to3AdapterWSConnectionMinimalThroughMqtt3)
    add_net_test_case(Mqtt5to3AdapterWithIoTConnectionThroughMqtt3)
    add_net_test_case(Mqtt5to3AdapterDirectConnectionWithMutualTLSThroughMqtt3)
    add_net_test_case(Mqtt5to3AdapterDirectConnectionMinimalThroughMqtt5)
    add_net_test_case(Mqtt5to3AdapterWSConnectionMinimalThroughMqtt5)
    add_net_test_case(Mqtt5to3AdapterWithIoTConnectionThroughMqtt5)
    add_net_test_case(Mqtt5to3AdapterDirectConnectionWithMutualTLSThroughMqtt5)
    add_net_test_case(Mqtt5to3AdapterOperations)
    add_net_test_case(Mqtt5to3AdapterNullPubAck)
    add_net_test_case(Mqtt5to3AdapterMultipleAdapters)

    # Mqtt Request-Response
    add_net_test_case(MqttRequestResponse_CreateDestroy5)
    add_net_test_case(MqttRequestResponse_CreateDestroy311)
    add_net_test_case(MqttRequestResponse_GetNamedShadowSuccessRejected311)
    add_net_test_case(MqttRequestResponse_GetNamedShadowSuccessRejected5)
    add_net_test_case(MqttRequestResponse_GetNamedShadowSuccessRejectedNoCorrelationToken311)
    add_net_test_case(MqttRequestResponse_GetNamedShadowSuccessRejectedNoCorrelationToken5)
    add_net_test_case(MqttRequestResponse_UpdateNamedShadowSuccessAccepted311)
    add_net_test_case(MqttRequestResponse_UpdateNamedShadowSuccessAccepted5)
    add_net_test_case(MqttRequestResponse_UpdateNamedShadowSuccessAcceptedNoCorrelationToken311)
    add_net_test_case(MqttRequestResponse_UpdateNamedShadowSuccessAcceptedNoCorrelationToken5)
    add_net_test_case(MqttRequestResponse_GetNamedShadowTimeout311)
    add_net_test_case(MqttRequestResponse_GetNamedShadowTimeout5)
    add_net_test_case(MqttRequestResponse_GetNamedShadowTimeoutNoCorrelationToken311)
    add_net_test_case(MqttRequestResponse_GetNamedShadowTimeoutNoCorrelationToken5)
    add_net_test_case(MqttRequestResponse_GetNamedShadowFailureOnClose311)
    add_net_test_case(MqttRequestResponse_GetNamedShadowFailureOnClose5)
    add_net_test_case(MqttRequestResponse_GetNamedShadowFailureOnCloseNoCorrelationToken311)
    add_net_test_case(MqttRequestResponse_GetNamedShadowFailureOnCloseNoCorrelationToken5)

    add_net_test_case(MqttRequestResponse_ShadowUpdatedStreamOpenCloseSuccess5)
    add_net_test_case(MqttRequestResponse_ShadowUpdatedStreamOpenCloseSuccess311)
    add_net_test_case(MqttRequestResponse_ShadowUpdatedStreamClientClosed5)
    add_net_test_case(MqttRequestResponse_ShadowUpdatedStreamClientClosed311)
    add_net_test_case(MqttRequestResponse_ShadowUpdatedStreamIncomingPublishSuccess5)
    add_net_test_case(MqttRequestResponse_ShadowUpdatedStreamIncomingPublishSuccess311)





endif()

add_test_case(RuleEngine)

if(AWS_HAS_CI_ENVIRONMENT AND NOT BYO_CRYPTO)
    add_test_case(CognitoCredentialsProviderGetSuccess)
    add_test_case(STSCredentialsProviderGetSuccess)

    if(ENABLE_PROXY_INTEGRATION_TESTS)
        add_test_case(CognitoCredentialsProviderGetSuccessProxy)
        add_test_case(STSCredentialsProviderGetSuccessProxy)
    endif()
endif()

add_test_case(CborSanityTest)
add_test_case(CborTimeStampTest)
add_test_case(CborLastErrorTest)

generate_cpp_test_driver(${TEST_BINARY_NAME})

aws_add_sanitizers(${TEST_BINARY_NAME})

 # set extra warning flags
if(AWS_WARNINGS_ARE_ERRORS)
    if(MSVC)
        target_compile_options(${TEST_BINARY_NAME} PRIVATE /W4 /WX /wd4068)
    else()
        target_compile_options(${TEST_BINARY_NAME} PRIVATE -Wall -Wno-long-long -Werror)
    endif()
endif()

add_custom_command(TARGET ${TEST_BINARY_NAME} PRE_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_directory
    ${CMAKE_CURRENT_SOURCE_DIR}/resources $<TARGET_FILE_DIR:${TEST_BINARY_NAME}>)
