use std::time::Duration;
use polyoxide_core::http::StatusCode;
use polyoxide_core::{AttemptInfo, Decision, Outcome, ResponseMeta, RetryConfig};
use crate::shared::error::retry_after_secs;
use crate::shared::weight::DEFAULT_BAN;
pub(crate) fn decide(
response: &ResponseMeta<'_>,
attempt: &AttemptInfo,
schedule: &RetryConfig,
until_next_minute: Duration,
) -> Decision {
let asked = retry_after_secs(response.retry_after());
match response.status {
StatusCode::TOO_MANY_REQUESTS if attempt.retries_left > 0 => Decision {
outcome: Outcome::Retry(Duration::ZERO),
hold: Some(
schedule
.retry_delay(attempt.attempt, response.retry_after())
.max(asked.unwrap_or_default()),
),
},
StatusCode::TOO_MANY_REQUESTS => Decision {
outcome: Outcome::Fail,
hold: Some(asked.unwrap_or(until_next_minute)),
},
StatusCode::IM_A_TEAPOT => Decision {
outcome: Outcome::Fail,
hold: Some(asked.unwrap_or(DEFAULT_BAN)),
},
status if status.is_success() => Decision {
outcome: Outcome::Done,
hold: None,
},
_ => Decision {
outcome: Outcome::Fail,
hold: None,
},
}
}