package ai.sentryagent.idp;

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;

/**
 * Lightweight in-process HTTP server for unit tests.
 * Uses the JDK's built-in {@code com.sun.net.httpserver.HttpServer}.
 */
public final class MockServer {

    private final HttpServer server;
    private final int port;

    public MockServer() throws IOException {
        server = HttpServer.create(new InetSocketAddress(0), 0);
        server.start();
        port = server.getAddress().getPort();
    }

    /** Base URL of the mock server (e.g. {@code "http://localhost:PORT"}). */
    public String baseUrl() {
        return "http://localhost:" + port;
    }

    /**
     * Registers a handler for an exact path.
     *
     * @param path         URL path (e.g. {@code "/api/v1/agents"})
     * @param statusCode   HTTP status code to return
     * @param responseBody JSON body to return (may be null for empty body)
     */
    public void addHandler(String path, int statusCode, String responseBody) {
        server.createContext(path, new StaticHandler(statusCode, responseBody));
    }

    /**
     * Registers a custom handler for an exact path.
     */
    public void addHandler(String path, HttpHandler handler) {
        server.createContext(path, handler);
    }

    /** Stops the server. */
    public void stop() {
        server.stop(0);
    }

    private static final class StaticHandler implements HttpHandler {
        private final int statusCode;
        private final byte[] body;

        StaticHandler(int statusCode, String body) {
            this.statusCode = statusCode;
            this.body = body != null ? body.getBytes(StandardCharsets.UTF_8) : new byte[0];
        }

        @Override
        public void handle(HttpExchange exchange) throws IOException {
            exchange.getResponseHeaders().set("Content-Type", "application/json");
            exchange.sendResponseHeaders(statusCode, body.length);
            try (OutputStream os = exchange.getResponseBody()) {
                os.write(body);
            }
        }
    }
}
