package ru.yandex.galois.clients.utils

import io.github.resilience4j.core.IntervalFunction
import io.github.resilience4j.kotlin.retry.RetryConfig
import io.github.resilience4j.retry.Retry
import io.netty.channel.ConnectTimeoutException
import io.netty.handler.ssl.SslHandshakeTimeoutException
import io.netty.handler.timeout.TimeoutException
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.HttpStatus
import org.springframework.web.reactive.function.client.WebClientResponseException

@Configuration
open class Retries(@Value("\${http.client.retries.maxAttempts}") private val maxAttempts: Int) {

    @Bean("httpRetry")
    open fun httpRetry(): Retry {
        return Retry.of("httpRetry", RetryConfig {
            maxAttempts(maxAttempts)
            intervalFunction(IntervalFunction.ofExponentialRandomBackoff())
            retryOnException{ e ->
                if (e is TimeoutException || e is SslHandshakeTimeoutException || e is ConnectTimeoutException) {
                    return@retryOnException true
                }
                if (e is WebClientResponseException) {
                    return@retryOnException e.statusCode.is5xxServerError
                        || e.statusCode == HttpStatus.TOO_MANY_REQUESTS
                }
                return@retryOnException false
            }
        })
    }

}
