// 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 axum::{
    Json,
    http::StatusCode,
    response::{IntoResponse, Response},
};
use log::warn;
use serde::{Deserialize, Serialize};
use snafu::{IntoError, Snafu};

#[derive(Debug, Snafu)]
pub enum Error {
    Service { source: pib_service_facade::Error },
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ApiError {
    pub message: String,
}

impl IntoResponse for Error {
    fn into_response(self) -> Response {
        warn!("Returning error response:\n{self:#?}");
        let mut response = Json(ApiError {
            message: format!("{self}"),
        })
        .into_response();
        *response.status_mut() = if self.is_not_found() {
            StatusCode::NOT_FOUND
        } else if self.is_forbidden() {
            StatusCode::FORBIDDEN
        } else if self.is_bad_request() {
            StatusCode::BAD_REQUEST
        } else {
            StatusCode::INTERNAL_SERVER_ERROR
        };
        response
    }
}

impl Error {
    pub fn is_not_found(&self) -> bool {
        matches!(
            self,
            Error::Service{source} if source.is_not_found()
        )
    }

    pub fn is_forbidden(&self) -> bool {
        matches!(self, Error::Service{source} if source.is_forbidden())
    }

    pub fn is_bad_request(&self) -> bool {
        matches!(self, Error::Service{source} if source.is_bad_request())
    }
}

impl<E: Into<pib_service_facade::Error>> From<E> for Error {
    fn from(value: E) -> Self {
        ServiceSnafu.into_error(value.into())
    }
}
