/*
 * SPDX-License-Identifier: GPL-3.0-or-later
 */
package com.runicgateway.app.data.api

import com.runicgateway.app.data.api.dto.MobileSsoExchangeRequest
import com.runicgateway.app.data.api.dto.MobileTokenResponse
import com.runicgateway.app.data.api.dto.SsoProviderDto
import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.Headers
import retrofit2.http.POST

/**
 * The native SSO bridge surface (PLAN.md §4.2, M9). Discovery lists the shard's
 * enabled providers; exchange trades a callback authorization code (+ its PKCE
 * verifier) for the same bearer pair as `/auth/mobile/login`.
 *
 * The redirect leg (`/auth/mobile/sso/start`) is **not** here — it is opened in a
 * Custom Tab as a URL (the browser follows the 302 through the IdP), not called as
 * an XHR. See [com.runicgateway.app.core.auth.sso.SsoAuthManager].
 *
 * Exchange is tagged [com.runicgateway.app.core.net.Http.NO_SESSION_HEADER]: it
 * carries no bearer (the user isn't signed in yet) and a `401` (bad/expired code or
 * PKCE mismatch) must never be misread as an expired session or trip the refresh
 * [com.runicgateway.app.core.net.TokenAuthenticator]. It returns a raw [Response]
 * so the caller can distinguish `401` from other failures.
 */
interface SsoApi {

    /** Public discovery — the enabled providers to render login buttons for. */
    @GET("api/v1/auth/providers")
    suspend fun providers(): List<SsoProviderDto>

    // Literal header value required by Retrofit @Headers; matches Http.NO_SESSION_HEADER.
    @Headers("X-Runic-No-Session: 1")
    @POST("api/v1/auth/mobile/sso/exchange")
    suspend fun exchange(@Body body: MobileSsoExchangeRequest): Response<MobileTokenResponse>
}
