// 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 axum::{Json, extract::State};
use pib_service_api_types::config::get::ResponseBody;
use pib_service_facade::Service;

use crate::Result;

pub(crate) async fn handle<E: Into<pib_service_facade::Error> + Send + Sync>(
    State(service): State<Arc<dyn Service<E>>>,
) -> Result<Json<ResponseBody>>
where
    crate::Error: From<E>,
{
    Ok(Json(service.handle_config_get().await?))
}

#[cfg(test)]
mod tests {
    use std::sync::Arc;

    use crate::Error;

    use super::{ResponseBody, handle};
    use axum::extract::State;
    use pib_service_api_types::config::oidc::OidcConfig;
    use pib_service_facade::MockService;
    use pretty_assertions::{assert_eq, assert_matches};

    #[tokio::test]
    async fn valid() {
        let mut service = MockService::<pib_service_facade::Error>::new();

        let config = ResponseBody {
            oidc: OidcConfig {
                issuer: "https://auth.example.com".to_string(),
                client_id: "pib-service-abcdef0011233".to_string(),
                client_secret: "v3rys3cr3t".to_string(),
            },
        };

        service.expect_handle_config_get().times(1).return_once(|| {
            Ok(ResponseBody {
                oidc: OidcConfig {
                    issuer: "https://auth.example.com".to_string(),
                    client_id: "pib-service-abcdef0011233".to_string(),
                    client_secret: "v3rys3cr3t".to_string(),
                },
            })
        });

        assert_eq!(handle(State(Arc::new(service))).await.unwrap().0, config);
    }

    #[tokio::test]
    async fn invalid() {
        let mut service = MockService::new();

        service
            .expect_handle_config_get()
            .times(1)
            .return_once(|| Err(pib_service_facade::Error::NotFound));

        assert_matches!(
            handle(State(Arc::new(service)),).await,
            Err(Error::Service {
                source: pib_service_facade::Error::NotFound
            })
        );
    }
}
