import { confirmProductionDeploy } from "../../common/middleware/confirm-production-deploy.js";
import { ENVIRONMENT_EXPLICIT_KEY, FETCHED_ENVIRONMENTS_KEY, } from "../../common/middleware/get-environment-param.js";
import { printCancellationToConsoleAndExitGracefully } from "../../common/output.js";
import { confirmLinkedValue } from "../../common/read-linked-config.js";
import { isInteractiveTerminal } from "../../common/terminal.js";
import { cleanupTest, setupTestEnvironment, TEST_ACCOUNT_NAME, TEST_AUTH_TOKEN, TEST_PROJECT_NAME, } from "./test-utils.js";
jest.mock("../../common/read-linked-config.js", () => ({
    __esModule: true,
    confirmLinkedValue: jest.fn().mockResolvedValue(true),
}));
jest.mock("../../common/terminal.js", () => ({
    __esModule: true,
    isInteractiveTerminal: jest.fn().mockReturnValue(true),
}));
jest.mock("../../common/output.js", () => ({
    __esModule: true,
    printCancellationToConsoleAndExitGracefully: jest
        .fn()
        .mockImplementation(() => {
        throw new Error("cancelled");
    }),
}));
function baseArgv(overrides = {}) {
    return {
        authToken: TEST_AUTH_TOKEN,
        account: TEST_ACCOUNT_NAME,
        project: TEST_PROJECT_NAME,
        ...overrides,
    };
}
describe("confirmProductionDeploy middleware", () => {
    beforeEach(() => {
        setupTestEnvironment();
        jest.clearAllMocks();
        jest.mocked(isInteractiveTerminal).mockReturnValue(true);
        jest.mocked(confirmLinkedValue).mockResolvedValue(true);
        jest
            .mocked(printCancellationToConsoleAndExitGracefully)
            .mockImplementation((() => {
            throw new Error("cancelled");
        }));
    });
    afterEach(() => {
        cleanupTest();
    });
    describe("when the env was inferred from a production branch and the terminal is interactive", () => {
        it("prompts with default No for branch 'main' and proceeds on accept", async () => {
            jest.mocked(confirmLinkedValue).mockResolvedValue(true);
            const argv = baseArgv({
                environment: "main",
                [ENVIRONMENT_EXPLICIT_KEY]: false,
            });
            await confirmProductionDeploy(argv);
            expect(confirmLinkedValue).toHaveBeenCalledTimes(1);
            const [message, options] = jest.mocked(confirmLinkedValue).mock.calls[0];
            expect(message).toContain("'main' production environment");
            expect(message).toContain(`'${TEST_PROJECT_NAME}'`);
            expect(message).toContain(`'${TEST_ACCOUNT_NAME}'`);
            expect(options).toEqual({ defaultYes: false });
            expect(printCancellationToConsoleAndExitGracefully).not.toHaveBeenCalled();
        });
        it("cancels via the graceful exit helper when the user declines", async () => {
            jest.mocked(confirmLinkedValue).mockResolvedValue(false);
            const argv = baseArgv({
                environment: "main",
                [ENVIRONMENT_EXPLICIT_KEY]: false,
            });
            await expect(confirmProductionDeploy(argv)).rejects.toThrow("cancelled");
            expect(confirmLinkedValue).toHaveBeenCalledTimes(1);
            expect(printCancellationToConsoleAndExitGracefully).toHaveBeenCalledWith("Deployment cancelled.");
        });
        it("prompts for branch 'master'", async () => {
            const argv = baseArgv({
                environment: "master",
                [ENVIRONMENT_EXPLICIT_KEY]: false,
            });
            await confirmProductionDeploy(argv);
            expect(confirmLinkedValue).toHaveBeenCalledTimes(1);
        });
        it("prompts for branch 'production' without duplicating the word in the message", async () => {
            const argv = baseArgv({
                environment: "production",
                [ENVIRONMENT_EXPLICIT_KEY]: false,
            });
            await confirmProductionDeploy(argv);
            expect(confirmLinkedValue).toHaveBeenCalledTimes(1);
            const [message] = jest.mocked(confirmLinkedValue).mock.calls[0];
            expect(message).toContain("the production environment");
            expect(message).not.toContain("'production' production environment");
        });
        it("prompts when the environment list reports environmentType=production for a non-standard name", async () => {
            const argv = baseArgv({
                environment: "live",
                [ENVIRONMENT_EXPLICIT_KEY]: false,
                [FETCHED_ENVIRONMENTS_KEY]: [
                    {
                        name: "live",
                        accountName: TEST_ACCOUNT_NAME,
                        projectName: TEST_PROJECT_NAME,
                        createdOn: null,
                        branchName: "live",
                        environmentType: "production",
                    },
                ],
            });
            await confirmProductionDeploy(argv);
            expect(confirmLinkedValue).toHaveBeenCalledTimes(1);
        });
    });
    describe("when the env is not production", () => {
        it("does not prompt for a feature branch", async () => {
            const argv = baseArgv({
                environment: "feature/login",
                [ENVIRONMENT_EXPLICIT_KEY]: false,
            });
            await confirmProductionDeploy(argv);
            expect(confirmLinkedValue).not.toHaveBeenCalled();
        });
        it("does not prompt when cached environmentType is not production", async () => {
            const argv = baseArgv({
                environment: "preview-1",
                [ENVIRONMENT_EXPLICIT_KEY]: false,
                [FETCHED_ENVIRONMENTS_KEY]: [
                    {
                        name: "preview-1",
                        accountName: TEST_ACCOUNT_NAME,
                        projectName: TEST_PROJECT_NAME,
                        createdOn: null,
                        branchName: "preview-1",
                        environmentType: "preview",
                    },
                ],
            });
            await confirmProductionDeploy(argv);
            expect(confirmLinkedValue).not.toHaveBeenCalled();
        });
    });
    describe("when the user opts out of the prompt", () => {
        it("does not prompt when --environment was passed explicitly", async () => {
            const argv = baseArgv({
                environment: "main",
                [ENVIRONMENT_EXPLICIT_KEY]: true,
            });
            await confirmProductionDeploy(argv);
            expect(confirmLinkedValue).not.toHaveBeenCalled();
        });
        it("does not prompt when --no-prompt is set (argv.prompt === false)", async () => {
            const argv = baseArgv({
                environment: "main",
                [ENVIRONMENT_EXPLICIT_KEY]: false,
                prompt: false,
            });
            await confirmProductionDeploy(argv);
            expect(confirmLinkedValue).not.toHaveBeenCalled();
        });
    });
    describe("when the terminal is non-interactive (CI/CD)", () => {
        it("does not prompt", async () => {
            jest.mocked(isInteractiveTerminal).mockReturnValue(false);
            const argv = baseArgv({
                environment: "main",
                [ENVIRONMENT_EXPLICIT_KEY]: false,
            });
            await confirmProductionDeploy(argv);
            expect(confirmLinkedValue).not.toHaveBeenCalled();
        });
    });
    describe("when argv.environment is missing or empty", () => {
        it("returns without prompting if environment is undefined", async () => {
            const argv = baseArgv({ [ENVIRONMENT_EXPLICIT_KEY]: false });
            await confirmProductionDeploy(argv);
            expect(confirmLinkedValue).not.toHaveBeenCalled();
        });
        it("returns without prompting if environment is empty string", async () => {
            const argv = baseArgv({
                environment: "",
                [ENVIRONMENT_EXPLICIT_KEY]: false,
            });
            await confirmProductionDeploy(argv);
            expect(confirmLinkedValue).not.toHaveBeenCalled();
        });
    });
});
//# sourceMappingURL=confirm-production-deploy.integration.test.js.map