import { describe, it, expect, beforeEach, vi } from "vitest";
import { ErrorCode } from "@pocketcoder/shared/constants";
import { handleProjectCreate, setProjectCreateGatewayClient } from "../project-create.js";
// Suppress logger output in tests
vi.mock("../../utils/logger.js", () => ({
    logger: {
        debug: vi.fn(),
        info: vi.fn(),
        warn: vi.fn(),
        error: vi.fn(),
    },
}));
// Mock project repository
vi.mock("../../db/repositories/projects.js", () => ({
    createProject: vi.fn(),
    getProjectByPath: vi.fn(),
}));
// Mock path validation
vi.mock("../../utils/validate-project-path.js", () => ({
    validateProjectPath: vi.fn(),
}));
// Mock project sync
vi.mock("../../gateway/messages/project-sync.js", () => ({
    sendProjectAdded: vi.fn(),
}));
import { createProject, getProjectByPath } from "../../db/repositories/projects.js";
import { validateProjectPath } from "../../utils/validate-project-path.js";
import { sendProjectAdded } from "../../gateway/messages/project-sync.js";
const mockCreateProject = vi.mocked(createProject);
const mockGetProjectByPath = vi.mocked(getProjectByPath);
const mockValidateProjectPath = vi.mocked(validateProjectPath);
const mockSendProjectAdded = vi.mocked(sendProjectAdded);
describe("project_create handler", () => {
    beforeEach(() => {
        vi.clearAllMocks();
    });
    function createRequest(path = "/home/dev/my-app", requestId = "req-1") {
        return {
            type: "project_create",
            requestId,
            payload: { path },
        };
    }
    function createSendCollector() {
        const responses = [];
        const send = (msg) => {
            responses.push(msg);
        };
        return { responses, send };
    }
    it("should register a valid project", async () => {
        mockValidateProjectPath.mockResolvedValue("/home/dev/my-app");
        mockGetProjectByPath.mockReturnValue(null);
        mockCreateProject.mockReturnValue({
            project_id: "proj-123",
            name: "my-app",
            path: "/home/dev/my-app",
            created_at: "2026-02-20T10:00:00Z",
            last_opened_at: null,
        });
        const { responses, send } = createSendCollector();
        await handleProjectCreate(createRequest(), send);
        expect(responses).toHaveLength(1);
        const resp = responses[0];
        expect(resp.type).toBe("project_create_response");
        expect(resp.requestId).toBe("req-1");
        expect(resp.error).toBeUndefined();
        expect(resp.payload).toBeDefined();
        expect(resp.payload.project.projectId).toBe("proj-123");
        expect(resp.payload.project.name).toBe("my-app");
        expect(resp.payload.project.path).toBe("/home/dev/my-app");
    });
    it("should reject non-existent path", async () => {
        mockValidateProjectPath.mockRejectedValue(new Error("Path does not exist: /nonexistent"));
        const { responses, send } = createSendCollector();
        await handleProjectCreate(createRequest("/nonexistent"), send);
        expect(responses).toHaveLength(1);
        const resp = responses[0];
        expect(resp.type).toBe("project_create_response");
        expect(resp.error).toBeDefined();
        expect(resp.error.code).toBe(ErrorCode.INVALID_PATH);
        expect(resp.error.message).toContain("Path does not exist");
    });
    it("should reject non-directory path", async () => {
        mockValidateProjectPath.mockRejectedValue(new Error("Not a directory: /home/dev/file.txt"));
        const { responses, send } = createSendCollector();
        await handleProjectCreate(createRequest("/home/dev/file.txt"), send);
        expect(responses).toHaveLength(1);
        const resp = responses[0];
        expect(resp.error).toBeDefined();
        expect(resp.error.code).toBe(ErrorCode.INVALID_PATH);
    });
    it("should reject already registered project", async () => {
        mockValidateProjectPath.mockResolvedValue("/home/dev/my-app");
        mockGetProjectByPath.mockReturnValue({
            project_id: "proj-existing",
            name: "my-app",
            path: "/home/dev/my-app",
            created_at: "2026-02-10T10:00:00Z",
            last_opened_at: null,
        });
        const { responses, send } = createSendCollector();
        await handleProjectCreate(createRequest(), send);
        expect(responses).toHaveLength(1);
        const resp = responses[0];
        expect(resp.error).toBeDefined();
        expect(resp.error.code).toBe(ErrorCode.PROJECT_ALREADY_EXISTS);
        expect(resp.error.message).toContain("already registered");
    });
    it("should reject request with missing path", async () => {
        const msg = {
            type: "project_create",
            requestId: "req-1",
            payload: {},
        };
        const { responses, send } = createSendCollector();
        await handleProjectCreate(msg, send);
        expect(responses).toHaveLength(1);
        const resp = responses[0];
        expect(resp.error).toBeDefined();
        expect(resp.error.code).toBe(ErrorCode.INVALID_REQUEST);
        expect(resp.error.message).toContain("path");
    });
    it("should send project_added to gateway when client is set", async () => {
        mockValidateProjectPath.mockResolvedValue("/home/dev/my-app");
        mockGetProjectByPath.mockReturnValue(null);
        mockCreateProject.mockReturnValue({
            project_id: "proj-123",
            name: "my-app",
            path: "/home/dev/my-app",
            created_at: "2026-02-20T10:00:00Z",
            last_opened_at: null,
        });
        const fakeClient = {};
        setProjectCreateGatewayClient(fakeClient);
        const { send } = createSendCollector();
        await handleProjectCreate(createRequest(), send);
        expect(mockSendProjectAdded).toHaveBeenCalledWith(fakeClient, {
            projectId: "proj-123",
            name: "my-app",
            path: "/home/dev/my-app",
        });
        // Reset gateway client
        setProjectCreateGatewayClient(null);
    });
    it("should include all required response fields", async () => {
        mockValidateProjectPath.mockResolvedValue("/home/dev/my-project");
        mockGetProjectByPath.mockReturnValue(null);
        mockCreateProject.mockReturnValue({
            project_id: "proj-456",
            name: "my-project",
            path: "/home/dev/my-project",
            created_at: "2026-02-20T12:00:00Z",
            last_opened_at: null,
        });
        const { responses, send } = createSendCollector();
        await handleProjectCreate(createRequest("/home/dev/my-project"), send);
        const resp = responses[0];
        expect(resp.type).toBe("project_create_response");
        expect(resp.requestId).toBe("req-1");
        expect(resp.payload.project).toHaveProperty("projectId");
        expect(resp.payload.project).toHaveProperty("name");
        expect(resp.payload.project).toHaveProperty("path");
    });
});
//# sourceMappingURL=project-create.test.js.map