#
# All rights reserved. No warranty, explicit or implicit, provided. In
# no event shall the author(s) be liable for any claim or damages.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
import fastapi
from headless.ext.oauth2.models import TokenResponse

from cbra.types import Request
from ..types import OIDCProvider
from ..types import FatalAuthorizationException
from ..types import IExternalAuthorizationState
from .localopenidprovider import LocalOpenIdProvider
from .localauthorizationrequeststate import LocalAuthorizationRequestState


__all__: list[str] = [
    'DownstreamTokenResponse'
]

async def get(
    request: Request,
    provider: OIDCProvider = LocalOpenIdProvider,
    state: IExternalAuthorizationState = LocalAuthorizationRequestState,
    code: str | None = fastapi.Query(
        default=None,
        title='Authorization code',
        description=(
            'The authorization code generated by the authorization server. '
            'Required if using the Authorization Code Flow and the response '
            'mode is `query`, otherwise this parameter is ignored.'
        )
    ),
    iss: str | None = fastapi.Query(
        default=None,
        title='Issuer',
        description=(
            'Identifies the authorization server that redirected to '
            'this endpoint, as defined in RFC 9207. If the client supports '
            'OAuth 2.0 Authorization Server Issuer Identification, then '
            'this parameter is **required**, if the response mode is not '
            'JWT Secured Authorization Response Mode (JARM) per RFC 9101.\n\n'
            'The `iss` parameter value is the issuer identifier of '
            'the authorization server that created the authorization '
            'response, as defined in RFC 8414.  Its value **must** '
            'be a URL that uses the `https` scheme without any '
            'query or fragment components.'
        )
    ),
    error: str | None = fastapi.Query(
        default=None,
        title="Error code",
        description=(
            "The error code returned by the authorization server if "
            "the user cancelled the request, refused consent, or "
            "failed to authenticate."
        )
    )
) -> TokenResponse:
    if error:
        return None # type: ignore
    if code is None:
        raise FatalAuthorizationException(
            "The 'code' parameter is missing from the downstream "
            "response."
        )
    return await state.obtain(
        provider=provider,
        code=code,
        url=f'{request.url.scheme}://{request.url.netloc}{request.url.path}',
        iss=iss
    )

DownstreamTokenResponse: TokenResponse = fastapi.Depends(get)