from __future__ import annotations

from fastapi import FastAPI
from fastapi.testclient import TestClient

from amsdal_ml.mcp_server.mcp_oauth.services.errors import OAuthAuthUnavailableError
from amsdal_ml.mcp_server.mcp_oauth.services.errors import OAuthBadRequestError
from amsdal_ml.mcp_server.mcp_oauth.services.errors import OAuthDisabledError
from amsdal_ml.mcp_server.mcp_oauth.services.errors import OAuthServerError
from amsdal_ml.mcp_server.mcp_oauth.services.errors import OAuthTokenGenerationError

HTTP_BAD_REQUEST = 400
HTTP_NOT_FOUND = 404
HTTP_INTERNAL_SERVER_ERROR = 500


def _build_app_with_raising_route(exc: Exception) -> FastAPI:
    app = FastAPI()

    @app.get('/boom')
    def boom() -> None:
        raise exc

    return app


def test_oauth_disabled_error_response_shape():
    response = TestClient(_build_app_with_raising_route(OAuthDisabledError())).get('/boom')
    assert response.status_code == HTTP_NOT_FOUND
    assert response.json()['detail'] == 'OAuth disabled'


def test_oauth_bad_request_error_response_shape():
    response = TestClient(_build_app_with_raising_route(OAuthBadRequestError('bad request'))).get('/boom')
    assert response.status_code == HTTP_BAD_REQUEST
    assert response.json()['detail'] == 'bad request'


def test_oauth_server_error_response_shape():
    response = TestClient(_build_app_with_raising_route(OAuthServerError('server error'))).get('/boom')
    assert response.status_code == HTTP_INTERNAL_SERVER_ERROR
    assert response.json()['detail'] == 'server error'


def test_oauth_auth_unavailable_error_response_shape():
    response = TestClient(_build_app_with_raising_route(OAuthAuthUnavailableError())).get('/boom')
    assert response.status_code == HTTP_INTERNAL_SERVER_ERROR
    assert response.json()['detail'] == 'amsdal.contrib.auth is not available'


def test_oauth_token_generation_error_response_shape():
    response = TestClient(_build_app_with_raising_route(OAuthTokenGenerationError())).get('/boom')
    assert response.status_code == HTTP_INTERNAL_SERVER_ERROR
    assert response.json()['detail'] == 'LoginSession token not generated'
