// SPDX-FileCopyrightText: Politik im Blick developers
// SPDX-FileCopyrightText: Wolfgang Silbermayr <wolfgang@silbermayr.at>
//
// SPDX-License-Identifier: AGPL-3.0-or-later OR EUPL-1.2

use std::sync::Arc;

use pib_service_api::{Auth, router};
use pib_service_api_auth::{ApiAuth, MockApiAuth};
use pib_service_facade::{Error, MockService, Service};

pub(crate) struct TestServerBuilder {
    pub api_auth: MockApiAuth,
    pub service: MockService<Error>,
}

impl TestServerBuilder {
    pub fn new() -> Self {
        let api_auth = MockApiAuth::new();
        let service = MockService::<Error>::new();
        Self { service, api_auth }
    }

    pub async fn build(self) -> TestServer {
        let TestServerBuilder { service, api_auth } = self;
        TestServer::create(Arc::new(api_auth), Arc::new(service)).await
    }
}

pub(crate) struct TestServer {
    pub server: axum_test::TestServer,
}

impl TestServer {
    pub fn builder() -> TestServerBuilder {
        TestServerBuilder::new()
    }

    pub async fn create<E>(api_auth: Arc<dyn ApiAuth>, service: Arc<dyn Service<E>>) -> Self
    where
        E: Into<pib_service_facade::Error> + Send + Sync + 'static,
    {
        let auth = Auth::new(api_auth);

        let router = router(auth, service).await;
        let server = axum_test::TestServer::new(router);
        Self { server }
    }
}

#[tokio::test]
async fn test_server_works() {
    let mut builder = TestServer::builder();

    builder
        .service
        .expect_handle_get()
        .return_once(|| Ok(pib_service_api_types::get::ResponseBody {}));

    let TestServer { server } = builder.build().await;

    let request = server.get("/");
    let response = request.await;

    assert_eq!(response.request_method(), "GET");
}
