/*
 * This file is part of LibEuFin.
 * Copyright (C) 2024 Taler Systems S.A.

 * LibEuFin is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation; either version 3, or
 * (at your option) any later version.

 * LibEuFin is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General
 * Public License for more details.

 * You should have received a copy of the GNU Affero General Public
 * License along with LibEuFin; see the file COPYING.  If not, see
 * <http://www.gnu.org/licenses/>
 */

import io.ktor.client.request.*
import io.ktor.http.*
import io.ktor.server.testing.*
import tech.libeufin.common.TalerErrorCode
import tech.libeufin.common.assertBadRequest
import tech.libeufin.common.assertUnauthorized
import tech.libeufin.common.test.abstractHistoryRoutine

// Test endpoint is correctly authenticated 
suspend fun ApplicationTestBuilder.authRoutine(
    method: HttpMethod,
    path: String,
    token: Boolean = true
) { 
    // No header
    client.request(path) {
        this.method = method
    }.assertUnauthorized(TalerErrorCode.GENERIC_PARAMETER_MISSING)

    // Bad header
    client.request(path) {
        this.method = method
        headers[HttpHeaders.Authorization] = "WTF"
    }.assertBadRequest(TalerErrorCode.GENERIC_HTTP_HEADERS_MALFORMED)

    // Wrong scheme
    if (token) {
        client.request(path) {
            this.method = method
            headers[HttpHeaders.Authorization] = "Basic bad-token"
        }.assertUnauthorized(TalerErrorCode.GENERIC_UNAUTHORIZED)
    } else {
        client.request(path) {
            this.method = method
            headers[HttpHeaders.Authorization] = "Bearer bad-token"
        }.assertUnauthorized(TalerErrorCode.GENERIC_UNAUTHORIZED)
    }

    // Bad token
    if (token) {
        client.request(path) {
            this.method = method
            headers[HttpHeaders.Authorization] = "Bearer bad-token"
        }.assertUnauthorized(TalerErrorCode.GENERIC_TOKEN_UNKNOWN)
    } else {
        client.request(path) {
            this.method = method
            basicAuth("username", "bad-password")
        }.assertUnauthorized(TalerErrorCode.GENERIC_TOKEN_UNKNOWN)
    }
}


suspend inline fun <reified B> ApplicationTestBuilder.historyRoutine(
    url: String,
    crossinline ids: (B) -> List<Long>,
    registered: List<suspend () -> Unit>,
    ignored: List<suspend () -> Unit> = listOf(),
    polling: Boolean = true
) {
    abstractHistoryRoutine(ids, registered, ignored, polling) { params: String ->
        client.getA("$url?$params")
    }
}