import nock from "nock";
import yargs from "yargs/yargs";
import listCommand from "../../cmds/list.js";
import { cleanupTest, RequestCapture, setupAuthenticatedNock, setupTestEnvironment, TEST_ACCOUNT_NAME, TEST_API_BASE, TEST_AUTH_TOKEN, TEST_PROJECT_NAME, } from "./test-utils.js";
async function executeListCommand(args) {
    const yargsInstance = yargs([])
        .command(listCommand)
        .help(false)
        .version(false)
        .exitProcess(false);
    const commandArgs = ["list"];
    if (args.account) {
        commandArgs.push("--account", args.account);
    }
    if (args.project) {
        commandArgs.push("--project", args.project);
    }
    if (args["api-key"]) {
        commandArgs.push("--api-key", args["api-key"]);
    }
    if (args["show-details"]) {
        commandArgs.push("--show-details");
    }
    if (args.output) {
        commandArgs.push("--output", args.output);
    }
    if (args["self-hosted-endpoint"]) {
        commandArgs.push("--self-hosted-endpoint", args["self-hosted-endpoint"]);
    }
    return await yargsInstance.parse(commandArgs);
}
const mockPrintResult = jest.mocked(require("../../common/output.js").printResultToConsoleAndExitGracefully);
const mockPrintTable = jest.mocked(require("../../common/output.js").printTableToConsoleAndExitGracefully);
const mockPrintJson = jest.mocked(require("../../common/output.js").printJsonToConsoleAndExitGracefully);
const mockPrintDiagnostics = jest.mocked(require("../../common/output.js").printDiagnosticsToConsole);
describe("List Command Integration Tests", () => {
    let requestCapture;
    beforeEach(() => {
        setupTestEnvironment();
        requestCapture = new RequestCapture();
        nock.disableNetConnect();
        jest.clearAllMocks();
    });
    afterEach(() => {
        cleanupTest();
        requestCapture.clear();
    });
    describe("SaaS version", () => {
        it("should intercept GET request to list deployments with account and project", async () => {
            const mockResponse = {
                data: [
                    { url: "https://test-project-production.zuplo.app" },
                    { url: "https://test-project-staging.zuplo.app" },
                ],
            };
            const scope = setupAuthenticatedNock(nock(TEST_API_BASE))
                .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/deployments`)
                .reply(200, mockResponse);
            scope.on("request", (req, interceptor, body) => {
                requestCapture.capture(req, interceptor, body);
            });
            await executeListCommand({
                account: TEST_ACCOUNT_NAME,
                project: TEST_PROJECT_NAME,
                "api-key": TEST_AUTH_TOKEN,
            });
            expect(scope.isDone()).toBe(true);
            const expectedOutput = "https://test-project-production.zuplo.app\nhttps://test-project-staging.zuplo.app";
            expect(mockPrintResult).toHaveBeenCalledWith(expectedOutput);
            const capturedRequests = requestCapture.getRequests();
            expect(capturedRequests).toMatchSnapshot("list-deployments-saas-requests");
        });
        it("should handle empty deployments list", async () => {
            const mockResponse = { data: [] };
            const scope = setupAuthenticatedNock(nock(TEST_API_BASE))
                .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/deployments`)
                .reply(200, mockResponse);
            scope.on("request", (req, interceptor, body) => {
                requestCapture.capture(req, interceptor, body);
            });
            await executeListCommand({
                account: TEST_ACCOUNT_NAME,
                project: TEST_PROJECT_NAME,
                "api-key": TEST_AUTH_TOKEN,
            });
            expect(scope.isDone()).toBe(true);
            expect(mockPrintResult).toHaveBeenCalledWith("");
            const capturedRequests = requestCapture.getRequests();
            expect(capturedRequests).toMatchSnapshot("list-deployments-empty-requests");
        });
        it("should output deployment details as a table when requested", async () => {
            const mockResponse = {
                data: [
                    {
                        projectName: TEST_PROJECT_NAME,
                        name: "test-project-main-3c1ac0c",
                        url: "https://test-project-main-3c1ac0c.zuplo.app",
                    },
                    {
                        projectName: TEST_PROJECT_NAME,
                        name: "test-project-main-47839f2",
                        url: "https://test-project-main-47839f2.d2.zuplo.dev",
                    },
                ],
            };
            const scope = setupAuthenticatedNock(nock(TEST_API_BASE))
                .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/deployments`)
                .reply(200, mockResponse);
            await executeListCommand({
                account: TEST_ACCOUNT_NAME,
                project: TEST_PROJECT_NAME,
                "api-key": TEST_AUTH_TOKEN,
                "show-details": true,
            });
            expect(scope.isDone()).toBe(true);
            expect(mockPrintTable).toHaveBeenCalledWith([
                {
                    "project-name": TEST_PROJECT_NAME,
                    name: "test-project-main-3c1ac0c",
                    url: "https://test-project-main-3c1ac0c.zuplo.app",
                },
                {
                    "project-name": TEST_PROJECT_NAME,
                    name: "test-project-main-47839f2",
                    url: "https://test-project-main-47839f2.d2.zuplo.dev",
                },
            ]);
        });
        it("should support the -d alias for details output", async () => {
            const mockResponse = {
                data: [
                    {
                        projectName: TEST_PROJECT_NAME,
                        name: "test-project-main-3c1ac0c",
                        url: "https://test-project-main-3c1ac0c.zuplo.app",
                    },
                ],
            };
            const scope = setupAuthenticatedNock(nock(TEST_API_BASE))
                .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/deployments`)
                .reply(200, mockResponse);
            const yargsInstance = yargs([])
                .command(listCommand)
                .help(false)
                .version(false)
                .exitProcess(false);
            await yargsInstance.parse([
                "list",
                "--account",
                TEST_ACCOUNT_NAME,
                "--project",
                TEST_PROJECT_NAME,
                "--api-key",
                TEST_AUTH_TOKEN,
                "-d",
            ]);
            expect(scope.isDone()).toBe(true);
            expect(mockPrintTable).toHaveBeenCalledWith([
                {
                    "project-name": TEST_PROJECT_NAME,
                    name: "test-project-main-3c1ac0c",
                    url: "https://test-project-main-3c1ac0c.zuplo.app",
                },
            ]);
        });
        it("should output JSON when requested", async () => {
            const mockResponse = {
                data: [
                    {
                        projectName: TEST_PROJECT_NAME,
                        name: "test-project-main-3c1ac0c",
                        url: "https://test-project-main-3c1ac0c.zuplo.app",
                    },
                ],
            };
            const scope = setupAuthenticatedNock(nock(TEST_API_BASE))
                .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/deployments`)
                .reply(200, mockResponse);
            await executeListCommand({
                account: TEST_ACCOUNT_NAME,
                project: TEST_PROJECT_NAME,
                "api-key": TEST_AUTH_TOKEN,
                output: "json",
            });
            expect(scope.isDone()).toBe(true);
            expect(mockPrintJson).toHaveBeenCalledWith([
                "https://test-project-main-3c1ac0c.zuplo.app",
            ]);
        });
        it("should output detailed JSON when requested", async () => {
            const mockResponse = {
                data: [
                    {
                        projectName: TEST_PROJECT_NAME,
                        name: "test-project-main-3c1ac0c",
                        url: "https://test-project-main-3c1ac0c.zuplo.app",
                    },
                ],
            };
            const scope = setupAuthenticatedNock(nock(TEST_API_BASE))
                .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/deployments`)
                .reply(200, mockResponse);
            await executeListCommand({
                account: TEST_ACCOUNT_NAME,
                project: TEST_PROJECT_NAME,
                "api-key": TEST_AUTH_TOKEN,
                "show-details": true,
                output: "json",
            });
            expect(scope.isDone()).toBe(true);
            expect(mockPrintJson).toHaveBeenCalledWith([
                {
                    projectName: TEST_PROJECT_NAME,
                    name: "test-project-main-3c1ac0c",
                    url: "https://test-project-main-3c1ac0c.zuplo.app",
                },
            ]);
        });
        it("should handle API error responses", async () => {
            const errorResponse = {
                error: "Not Found",
                message: "Project not found",
                statusCode: 404,
            };
            const scope = setupAuthenticatedNock(nock(TEST_API_BASE))
                .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/deployments`)
                .reply(404, errorResponse);
            scope.on("request", (req, interceptor, body) => {
                requestCapture.capture(req, interceptor, body);
            });
            await expect(executeListCommand({
                account: TEST_ACCOUNT_NAME,
                project: TEST_PROJECT_NAME,
                "api-key": TEST_AUTH_TOKEN,
            })).rejects.toThrow("Failed to list deployed APIs");
            expect(scope.isDone()).toBe(true);
            expect(mockPrintDiagnostics).toHaveBeenCalled();
            const capturedRequests = requestCapture.getRequests();
            expect(capturedRequests).toMatchSnapshot("list-deployments-error-requests");
        });
    });
    describe("Self-hosted version", () => {
        it("should intercept GET request to self-hosted endpoint", async () => {
            const selfHostedEndpoint = "https://my-zuplo.company.com";
            const mockResponse = {
                data: [
                    {
                        projectName: "project-1",
                        deploymentName: "deployment-1",
                        deploymentUrl: "https://my-zuplo.company.com/project1",
                    },
                    {
                        projectName: "project-2",
                        deploymentName: "deployment-2",
                        deploymentUrl: "https://my-zuplo.company.com/project2",
                    },
                ],
            };
            const scope = setupAuthenticatedNock(nock(selfHostedEndpoint))
                .get("/v1/deployments")
                .reply(200, mockResponse);
            scope.on("request", (req, interceptor, body) => {
                requestCapture.capture(req, interceptor, body);
            });
            await executeListCommand({
                account: TEST_ACCOUNT_NAME,
                project: TEST_PROJECT_NAME,
                "api-key": TEST_AUTH_TOKEN,
                "self-hosted-endpoint": selfHostedEndpoint,
            });
            expect(scope.isDone()).toBe(true);
            const expectedOutput = "https://my-zuplo.company.com/project1\nhttps://my-zuplo.company.com/project2";
            expect(mockPrintResult).toHaveBeenCalledWith(expectedOutput);
            const capturedRequests = requestCapture.getRequests();
            expect(capturedRequests).toMatchSnapshot("list-deployments-self-hosted-requests");
        });
    });
    describe("Request headers validation", () => {
        it("should include correct authorization headers", async () => {
            const mockResponse = { data: [{ url: "https://test.zuplo.app" }] };
            const scope = nock(TEST_API_BASE)
                .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/deployments`)
                .matchHeader("authorization", `Bearer ${TEST_AUTH_TOKEN}`)
                .reply(200, mockResponse);
            scope.on("request", (req, interceptor, body) => {
                requestCapture.capture(req, interceptor, body);
            });
            await executeListCommand({
                account: TEST_ACCOUNT_NAME,
                project: TEST_PROJECT_NAME,
                "api-key": TEST_AUTH_TOKEN,
            });
            expect(scope.isDone()).toBe(true);
            expect(mockPrintResult).toHaveBeenCalledWith("https://test.zuplo.app");
            const capturedRequests = requestCapture.getRequests();
            expect(capturedRequests).toMatchSnapshot("list-deployments-headers-validation");
        });
    });
});
//# sourceMappingURL=list.integration.test.js.map