import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { createControlPlane } from "../../server.js";
import { clearShutdownHandlers, registerShutdownHandler } from "../../../services/shutdown.js";
import { setExitFn } from "../stop.js";
describe("/stop endpoint", () => {
    let server;
    let address;
    beforeEach(async () => {
        clearShutdownHandlers();
        // Override exit function to prevent process.exit during tests
        setExitFn(() => { });
        server = createControlPlane({ host: "127.0.0.1", port: 0 });
        address = await server.start();
    });
    afterEach(async () => {
        clearShutdownHandlers();
        setExitFn(() => { });
        try {
            await server.stop();
        }
        catch {
            // Server may already be stopped
        }
    });
    it("should return stopping status", async () => {
        const response = await fetch(`${address}/stop`, { method: "POST" });
        const body = (await response.json());
        expect(response.status).toBe(200);
        expect(body).toEqual({ status: "stopping" });
    });
    it("should trigger shutdown sequence", async () => {
        const handlerCalled = vi.fn();
        registerShutdownHandler("test-handler", handlerCalled);
        const response = await fetch(`${address}/stop`, { method: "POST" });
        expect(response.status).toBe(200);
        // Wait for setImmediate + shutdown to complete
        await new Promise((resolve) => setTimeout(resolve, 100));
        expect(handlerCalled).toHaveBeenCalledOnce();
    });
    it("should be idempotent", async () => {
        const handlerCalled = vi.fn();
        registerShutdownHandler("test-handler", handlerCalled);
        // First stop
        const response1 = await fetch(`${address}/stop`, { method: "POST" });
        expect(response1.status).toBe(200);
        // Wait for shutdown to start
        await new Promise((resolve) => setTimeout(resolve, 100));
        // Second stop should also return 200 with stopping status
        try {
            const response2 = await fetch(`${address}/stop`, { method: "POST" });
            const body2 = (await response2.json());
            expect(body2.status).toBe("stopping");
        }
        catch {
            // Server might have already closed - that's also acceptable idempotent behavior
        }
        // Handler should only be called once
        expect(handlerCalled).toHaveBeenCalledOnce();
    });
    it("should run shutdown handlers in reverse order", async () => {
        const order = [];
        registerShutdownHandler("first", () => {
            order.push("first");
        });
        registerShutdownHandler("second", () => {
            order.push("second");
        });
        registerShutdownHandler("third", () => {
            order.push("third");
        });
        await fetch(`${address}/stop`, { method: "POST" });
        await new Promise((resolve) => setTimeout(resolve, 100));
        expect(order).toEqual(["third", "second", "first"]);
    });
    it("should handle handler errors without crashing", async () => {
        const goodHandler = vi.fn();
        registerShutdownHandler("failing", () => {
            throw new Error("Handler error");
        });
        registerShutdownHandler("good", goodHandler);
        await fetch(`${address}/stop`, { method: "POST" });
        await new Promise((resolve) => setTimeout(resolve, 100));
        // Good handler should still be called despite earlier handler failing
        // (good is registered second, so called first in LIFO order)
        expect(goodHandler).toHaveBeenCalledOnce();
    });
    it("should only accept POST method", async () => {
        const response = await fetch(`${address}/stop`, { method: "GET" });
        expect(response.status).toBe(404);
    });
});
//# sourceMappingURL=stop.test.js.map