use futures_util::ready;
use pin_project_lite::pin_project;
use std::time::Duration;
use std::{
    future::Future,
    pin::Pin,
    task::{Context, Poll},
};
use tower_service::Service;

use crate::util::Oneshot;

/// A policy which specifies how long each request should be delayed for.
pub trait Policy<Request> {
    fn delay(&self, req: &Request) -> Duration;
}

/// A middleware which delays sending the request to the underlying service
/// for an amount of time specified by the policy.
#[derive(Debug)]
pub struct Delay<P, S> {
    policy: P,
    service: S,
}

pin_project! {
    #[derive(Debug)]
    pub struct ResponseFuture<Request, S>
    where
        S: Service<Request>,
    {
        service: Option<S>,
        #[pin]
        state: State<Request, Oneshot<S, Request>>,
    }
}

pin_project! {
    #[project = StateProj]
    #[derive(Debug)]
    enum State<Request, F> {
        Delaying {
            #[pin]
            delay: tokio::time::Sleep,
            req: Option<Request>,
        },
        Called {
            #[pin]
            fut: F,
        },
    }
}

impl<Request, F> State<Request, F> {
    fn delaying(delay: tokio::time::Sleep, req: Option<Request>) -> Self {
        Self::Delaying { delay, req }
    }

    fn called(fut: F) -> Self {
        Self::Called { fut }
    }
}

impl<P, S> Delay<P, S> {
    pub fn new<Request>(policy: P, service: S) -> Self
    where
        P: Policy<Request>,
        S: Service<Request> + Clone,
        S::Error: Into<crate::BoxError>,
    {
        Delay { policy, service }
    }
}

impl<Request, P, S> Service<Request> for Delay<P, S>
where
    P: Policy<Request>,
    S: Service<Request> + Clone,
    S::Error: Into<crate::BoxError>,
{
    type Response = S::Response;
    type Error = crate::BoxError;
    type Future = ResponseFuture<Request, S>;

    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
        // Calling self.service.poll_ready would reserve a slot for the delayed request,
        // potentially well in advance of actually making it.  Instead, signal readiness here and
        // treat the service as a Oneshot in the future.
        Poll::Ready(Ok(()))
    }

    fn call(&mut self, request: Request) -> Self::Future {
        let delay = self.policy.delay(&request);
        ResponseFuture {
            service: Some(self.service.clone()),
            state: State::delaying(tokio::time::sleep(delay), Some(request)),
        }
    }
}

impl<Request, S, T, E> Future for ResponseFuture<Request, S>
where
    E: Into<crate::BoxError>,
    S: Service<Request, Response = T, Error = E>,
{
    type Output = Result<T, crate::BoxError>;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        let mut this = self.project();

        loop {
            match this.state.as_mut().project() {
                StateProj::Delaying { delay, req } => {
                    ready!(delay.poll(cx));
                    let req = req.take().expect("Missing request in delay");
                    let svc = this.service.take().expect("Missing service in delay");
                    let fut = Oneshot::new(svc, req);
                    this.state.set(State::called(fut));
                }
                StateProj::Called { fut } => {
                    return fut.poll(cx).map_err(Into::into);
                }
            };
        }
    }
}
