import { describe, it, expect, vi, beforeEach } from "vitest";
import { ErrorCode } from "@pocketcoder/shared/constants";
// Mock logger
vi.mock("../../utils/logger.js", () => ({
    logger: {
        debug: vi.fn(),
        info: vi.fn(),
        warn: vi.fn(),
        error: vi.fn(),
    },
}));
// Mock proxy
vi.mock("../proxy.js", () => ({
    proxyToOpenCode: vi.fn(),
}));
import { proxyToOpenCode } from "../proxy.js";
import { handlePermissionReply } from "../permission-reply.js";
const mockProxy = vi.mocked(proxyToOpenCode);
describe("handlePermissionReply", () => {
    let responses;
    let send;
    beforeEach(() => {
        responses = [];
        send = (msg) => {
            responses.push(msg);
        };
        mockProxy.mockReset();
    });
    function createRequest(reply = "once", permissionId = "perm-123") {
        return {
            type: "permission_reply",
            requestId: "req-1",
            sessionId: "session-1",
            payload: {
                permissionId,
                reply: reply,
            },
        };
    }
    it("should handle once reply", async () => {
        mockProxy.mockResolvedValueOnce({
            status: 200,
            headers: {},
            body: JSON.stringify({ ok: true }),
        });
        await handlePermissionReply(createRequest("once"), send);
        expect(responses).toHaveLength(1);
        expect(responses[0].type).toBe("permission_reply_response");
        expect(responses[0].error).toBeUndefined();
        expect(responses[0].payload?.status).toBe(200);
        expect(mockProxy).toHaveBeenCalledWith({
            method: "POST",
            path: "/permission/perm-123/reply",
            body: JSON.stringify({ reply: "once" }),
        });
    });
    it("should handle always reply", async () => {
        mockProxy.mockResolvedValueOnce({
            status: 200,
            headers: {},
            body: JSON.stringify({ ok: true }),
        });
        await handlePermissionReply(createRequest("always"), send);
        expect(responses).toHaveLength(1);
        expect(responses[0].error).toBeUndefined();
        expect(responses[0].payload?.status).toBe(200);
        expect(mockProxy).toHaveBeenCalledWith({
            method: "POST",
            path: "/permission/perm-123/reply",
            body: JSON.stringify({ reply: "always" }),
        });
    });
    it("should handle reject reply", async () => {
        mockProxy.mockResolvedValueOnce({
            status: 200,
            headers: {},
            body: JSON.stringify({ ok: true }),
        });
        await handlePermissionReply(createRequest("reject"), send);
        expect(responses).toHaveLength(1);
        expect(responses[0].error).toBeUndefined();
        expect(responses[0].payload?.status).toBe(200);
        expect(mockProxy).toHaveBeenCalledWith({
            method: "POST",
            path: "/permission/perm-123/reply",
            body: JSON.stringify({ reply: "reject" }),
        });
    });
    it("should reject invalid reply", async () => {
        await handlePermissionReply(createRequest("invalid-value"), send);
        expect(responses).toHaveLength(1);
        expect(responses[0].error).toBeDefined();
        expect(responses[0].error.code).toBe(ErrorCode.INVALID_REQUEST);
        expect(responses[0].error.message).toContain("Invalid reply value");
        expect(mockProxy).not.toHaveBeenCalled();
    });
    it("should reject empty permissionId", async () => {
        await handlePermissionReply(createRequest("once", ""), send);
        expect(responses).toHaveLength(1);
        expect(responses[0].error).toBeDefined();
        expect(responses[0].error.code).toBe(ErrorCode.INVALID_REQUEST);
        expect(responses[0].error.message).toContain("permissionId");
        expect(mockProxy).not.toHaveBeenCalled();
    });
    it("should handle OPENCODE_UNREACHABLE error", async () => {
        mockProxy.mockRejectedValueOnce(new Error("OPENCODE_UNREACHABLE"));
        await handlePermissionReply(createRequest("once"), send);
        expect(responses).toHaveLength(1);
        expect(responses[0].error).toBeDefined();
        expect(responses[0].error.code).toBe(ErrorCode.OPENCODE_UNREACHABLE);
    });
    it("should handle TIMEOUT error", async () => {
        mockProxy.mockRejectedValueOnce(new Error("TIMEOUT"));
        await handlePermissionReply(createRequest("once"), send);
        expect(responses).toHaveLength(1);
        expect(responses[0].error).toBeDefined();
        expect(responses[0].error.code).toBe(ErrorCode.TIMEOUT);
    });
    it("should forward OpenCode response body", async () => {
        mockProxy.mockResolvedValueOnce({
            status: 200,
            headers: {},
            body: JSON.stringify({ permission: "granted", id: "perm-123" }),
        });
        await handlePermissionReply(createRequest("once"), send);
        expect(responses).toHaveLength(1);
        expect(responses[0].payload?.body).toEqual({ permission: "granted", id: "perm-123" });
    });
    it("should handle empty response body from OpenCode", async () => {
        mockProxy.mockResolvedValueOnce({
            status: 204,
            headers: {},
        });
        await handlePermissionReply(createRequest("once"), send);
        expect(responses).toHaveLength(1);
        expect(responses[0].payload?.status).toBe(204);
        expect(responses[0].payload?.body).toBeUndefined();
    });
});
//# sourceMappingURL=permission-reply.test.js.map