/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { describe, it, expect, vi, beforeEach } from 'vitest';
import * as path from 'node:path';
import { loadCliConfig } from './config.js';
import { createTestMergedSettings } from './settings.js';
import * as ServerConfig from '@google/gemini-cli-core';
import { isWorkspaceTrusted } from './trustedFolders.js';
import * as Policy from './policy.js';
// Mock dependencies
vi.mock('./trustedFolders.js', () => ({
    isWorkspaceTrusted: vi.fn(),
}));
const mockCheckIntegrity = vi.fn();
const mockAcceptIntegrity = vi.fn();
vi.mock('@google/gemini-cli-core', async () => {
    const actual = await vi.importActual('@google/gemini-cli-core');
    return {
        ...actual,
        loadServerHierarchicalMemory: vi.fn().mockResolvedValue({
            memoryContent: '',
            fileCount: 0,
            filePaths: [],
        }),
        createPolicyEngineConfig: vi.fn().mockResolvedValue({
            rules: [],
            checkers: [],
        }),
        getVersion: vi.fn().mockResolvedValue('test-version'),
        PolicyIntegrityManager: vi.fn().mockImplementation(() => ({
            checkIntegrity: mockCheckIntegrity,
            acceptIntegrity: mockAcceptIntegrity,
        })),
        IntegrityStatus: { MATCH: 'match', NEW: 'new', MISMATCH: 'mismatch' },
        debugLogger: {
            warn: vi.fn(),
            error: vi.fn(),
        },
        isHeadlessMode: vi.fn().mockReturnValue(false), // Default to interactive
    };
});
describe('Workspace-Level Policy CLI Integration', () => {
    const MOCK_CWD = process.cwd();
    beforeEach(() => {
        vi.clearAllMocks();
        Policy.setDisableWorkspacePolicies(false);
        // Default to MATCH for existing tests
        mockCheckIntegrity.mockResolvedValue({
            status: 'match',
            hash: 'test-hash',
            fileCount: 1,
        });
        vi.mocked(ServerConfig.isHeadlessMode).mockReturnValue(false);
    });
    it('should have getWorkspacePoliciesDir on Storage class', () => {
        const storage = new ServerConfig.Storage(MOCK_CWD);
        expect(storage.getWorkspacePoliciesDir).toBeDefined();
        expect(typeof storage.getWorkspacePoliciesDir).toBe('function');
    });
    it('should pass workspacePoliciesDir to createPolicyEngineConfig when folder is trusted', async () => {
        vi.mocked(isWorkspaceTrusted).mockReturnValue({
            isTrusted: true,
            source: 'file',
        });
        const settings = createTestMergedSettings();
        const argv = { query: 'test' };
        await loadCliConfig(settings, 'test-session', argv, { cwd: MOCK_CWD });
        expect(ServerConfig.createPolicyEngineConfig).toHaveBeenCalledWith(expect.objectContaining({
            workspacePoliciesDir: expect.stringContaining(path.join('.gemini', 'policies')),
        }), expect.anything());
    });
    it('should NOT pass workspacePoliciesDir to createPolicyEngineConfig when folder is NOT trusted', async () => {
        vi.mocked(isWorkspaceTrusted).mockReturnValue({
            isTrusted: false,
            source: 'file',
        });
        const settings = createTestMergedSettings();
        const argv = { query: 'test' };
        await loadCliConfig(settings, 'test-session', argv, { cwd: MOCK_CWD });
        expect(ServerConfig.createPolicyEngineConfig).toHaveBeenCalledWith(expect.objectContaining({
            workspacePoliciesDir: undefined,
        }), expect.anything());
    });
    it('should NOT pass workspacePoliciesDir if integrity is NEW but fileCount is 0', async () => {
        vi.mocked(isWorkspaceTrusted).mockReturnValue({
            isTrusted: true,
            source: 'file',
        });
        mockCheckIntegrity.mockResolvedValue({
            status: 'new',
            hash: 'hash',
            fileCount: 0,
        });
        const settings = createTestMergedSettings();
        const argv = { query: 'test' };
        await loadCliConfig(settings, 'test-session', argv, { cwd: MOCK_CWD });
        expect(ServerConfig.createPolicyEngineConfig).toHaveBeenCalledWith(expect.objectContaining({
            workspacePoliciesDir: undefined,
        }), expect.anything());
    });
    it('should automatically accept and load workspacePoliciesDir if integrity MISMATCH in non-interactive mode', async () => {
        vi.mocked(isWorkspaceTrusted).mockReturnValue({
            isTrusted: true,
            source: 'file',
        });
        mockCheckIntegrity.mockResolvedValue({
            status: 'mismatch',
            hash: 'new-hash',
            fileCount: 1,
        });
        vi.mocked(ServerConfig.isHeadlessMode).mockReturnValue(true); // Non-interactive
        const settings = createTestMergedSettings();
        const argv = { prompt: 'do something' };
        await loadCliConfig(settings, 'test-session', argv, { cwd: MOCK_CWD });
        expect(mockAcceptIntegrity).toHaveBeenCalledWith('workspace', MOCK_CWD, 'new-hash');
        expect(ServerConfig.createPolicyEngineConfig).toHaveBeenCalledWith(expect.objectContaining({
            workspacePoliciesDir: expect.stringContaining(path.join('.gemini', 'policies')),
        }), expect.anything());
    });
    it('should automatically accept and load workspacePoliciesDir if integrity MISMATCH in interactive mode when AUTO_ACCEPT is true', async () => {
        vi.mocked(isWorkspaceTrusted).mockReturnValue({
            isTrusted: true,
            source: 'file',
        });
        mockCheckIntegrity.mockResolvedValue({
            status: 'mismatch',
            hash: 'new-hash',
            fileCount: 1,
        });
        vi.mocked(ServerConfig.isHeadlessMode).mockReturnValue(false); // Interactive
        const settings = createTestMergedSettings();
        const argv = {
            query: 'test',
            promptInteractive: 'test',
        };
        const config = await loadCliConfig(settings, 'test-session', argv, {
            cwd: MOCK_CWD,
        });
        expect(config.getPolicyUpdateConfirmationRequest()).toBeUndefined();
        expect(mockAcceptIntegrity).toHaveBeenCalledWith('workspace', MOCK_CWD, 'new-hash');
        expect(ServerConfig.createPolicyEngineConfig).toHaveBeenCalledWith(expect.objectContaining({
            workspacePoliciesDir: expect.stringContaining(path.join('.gemini', 'policies')),
        }), expect.anything());
    });
    it('should automatically accept and load workspacePoliciesDir if integrity is NEW in interactive mode when AUTO_ACCEPT is true', async () => {
        vi.mocked(isWorkspaceTrusted).mockReturnValue({
            isTrusted: true,
            source: 'file',
        });
        mockCheckIntegrity.mockResolvedValue({
            status: 'new',
            hash: 'new-hash',
            fileCount: 5,
        });
        vi.mocked(ServerConfig.isHeadlessMode).mockReturnValue(false); // Interactive
        const settings = createTestMergedSettings();
        const argv = { query: 'test' };
        const config = await loadCliConfig(settings, 'test-session', argv, {
            cwd: MOCK_CWD,
        });
        expect(config.getPolicyUpdateConfirmationRequest()).toBeUndefined();
        expect(mockAcceptIntegrity).toHaveBeenCalledWith('workspace', MOCK_CWD, 'new-hash');
        expect(ServerConfig.createPolicyEngineConfig).toHaveBeenCalledWith(expect.objectContaining({
            workspacePoliciesDir: expect.stringContaining(path.join('.gemini', 'policies')),
        }), expect.anything());
    });
    it('should set policyUpdateConfirmationRequest if integrity MISMATCH in interactive mode when AUTO_ACCEPT is false', async () => {
        // Monkey patch autoAcceptWorkspacePolicies using setter
        const originalValue = Policy.autoAcceptWorkspacePolicies;
        Policy.setAutoAcceptWorkspacePolicies(false);
        try {
            vi.mocked(isWorkspaceTrusted).mockReturnValue({
                isTrusted: true,
                source: 'file',
            });
            mockCheckIntegrity.mockResolvedValue({
                status: 'mismatch',
                hash: 'new-hash',
                fileCount: 1,
            });
            vi.mocked(ServerConfig.isHeadlessMode).mockReturnValue(false); // Interactive
            const settings = createTestMergedSettings();
            const argv = {
                query: 'test',
                promptInteractive: 'test',
            };
            const config = await loadCliConfig(settings, 'test-session', argv, {
                cwd: MOCK_CWD,
            });
            expect(config.getPolicyUpdateConfirmationRequest()).toEqual({
                scope: 'workspace',
                identifier: MOCK_CWD,
                policyDir: expect.stringContaining(path.join('.gemini', 'policies')),
                newHash: 'new-hash',
            });
            expect(ServerConfig.createPolicyEngineConfig).toHaveBeenCalledWith(expect.objectContaining({
                workspacePoliciesDir: undefined,
            }), expect.anything());
        }
        finally {
            // Restore for other tests
            Policy.setAutoAcceptWorkspacePolicies(originalValue);
        }
    });
});
//# sourceMappingURL=workspace-policy-cli.test.js.map