package io.quarkiverse.openapi.generator.it.security;

import java.util.List;

import jakarta.inject.Inject;

import org.acme.openapi.slack.api.MessageApi;
import org.acme.openapi.slack.model.SendMessageRequest;
import org.acme.openapi.slack.model.SendMessageResponse;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
import com.github.tomakehurst.wiremock.verification.LoggedRequest;

import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.junit.QuarkusTest;

@QuarkusTestResource(WiremockSlackServer.class)
@QuarkusTest
public class CheckHeadersBearerTokenTest {

    // injected by quarkus test resource
    WireMockServer slackServer;

    // generated by OpenAPI
    @RestClient
    @Inject
    MessageApi messageApi;

    @Test
    void testNoDuplicateHeaders() {
        SendMessageRequest sendMessageRequest = new SendMessageRequest();
        sendMessageRequest.setChannel("#test");
        sendMessageRequest.setText("Hello World");
        SendMessageResponse response = messageApi.sendSlackMessage(sendMessageRequest);
        Assertions.assertNotNull(response, "Expected a non-null response");

        List<LoggedRequest> requests = slackServer.findAll(
                WireMock.postRequestedFor(WireMock.urlEqualTo("/api/chat.postMessage")));
        Assertions.assertEquals(1, requests.size(), "Expected exactly one HTTP request");

        LoggedRequest req = requests.get(0);

        String contentLength = req.getHeader("Content-Length");
        Assertions.assertNotNull(contentLength, "Content-Length header should be present");
        Assertions.assertTrue(
                Integer.parseInt(contentLength) > 0,
                "Content-Length should be a positive integer");

        for (String headerName : req.getAllHeaderKeys()) {
            List<String> values = req.getHeaders().getHeader(headerName).values();
            Assertions.assertEquals(
                    1,
                    values.size(),
                    () -> String.format(
                            "Header '%s' is duplicated; values: %s",
                            headerName, values));
        }
    }

}
