import { jsx as _jsx } from "react/jsx-runtime";
/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { persistentStateMock, renderWithProviders, } from '../../test-utils/render.js';
import { createMockSettings } from '../../test-utils/settings.js';
import { waitFor } from '../../test-utils/async.js';
import { Notifications } from './Notifications.js';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { useAppContext } from '../contexts/AppContext.js';
import { useUIState } from '../contexts/UIStateContext.js';
import { useIsScreenReaderEnabled } from 'ink';
import * as fs from 'node:fs/promises';
import { act } from 'react';
import { WarningPriority } from '@google/gemini-cli-core';
// Mock dependencies
vi.mock('../contexts/AppContext.js');
vi.mock('../contexts/UIStateContext.js');
vi.mock('ink', async () => {
    const actual = await vi.importActual('ink');
    return {
        ...actual,
        useIsScreenReaderEnabled: vi.fn(),
    };
});
vi.mock('node:fs/promises', async () => {
    const actual = await vi.importActual('node:fs/promises');
    return {
        ...actual,
        access: vi.fn(),
        writeFile: vi.fn(),
        mkdir: vi.fn().mockResolvedValue(undefined),
        unlink: vi.fn().mockResolvedValue(undefined),
    };
});
vi.mock('node:os', async (importOriginal) => {
    const actual = await importOriginal();
    return {
        ...actual,
        default: {
            ...actual,
            homedir: () => '/mock/home',
        },
        homedir: () => '/mock/home',
    };
});
vi.mock('node:path', async () => {
    const actual = await vi.importActual('node:path');
    return {
        ...actual,
        default: actual.posix,
    };
});
vi.mock('@google/gemini-cli-core', async (importOriginal) => {
    const actual = await importOriginal();
    return {
        ...actual,
        GEMINI_DIR: '.gemini',
        homedir: () => '/mock/home',
        WarningPriority: {
            Low: 'low',
            High: 'high',
        },
        Storage: {
            ...actual.Storage,
            getGlobalTempDir: () => '/mock/temp',
            getGlobalSettingsPath: () => '/mock/home/.gemini/settings.json',
        },
    };
});
describe('Notifications', () => {
    const mockUseAppContext = vi.mocked(useAppContext);
    const mockUseUIState = vi.mocked(useUIState);
    const mockUseIsScreenReaderEnabled = vi.mocked(useIsScreenReaderEnabled);
    const mockFsAccess = vi.mocked(fs.access);
    const mockFsUnlink = vi.mocked(fs.unlink);
    let settings;
    beforeEach(() => {
        vi.clearAllMocks();
        persistentStateMock.reset();
        settings = createMockSettings({
            ui: { useAlternateBuffer: true },
        });
        mockUseAppContext.mockReturnValue({
            startupWarnings: [],
            version: '1.0.0',
        });
        mockUseUIState.mockReturnValue({
            initError: null,
            streamingState: 'idle',
            updateInfo: null,
        });
        mockUseIsScreenReaderEnabled.mockReturnValue(false);
    });
    it('renders nothing when no notifications', async () => {
        const { lastFrame, waitUntilReady, unmount } = renderWithProviders(_jsx(Notifications, {}), {
            settings,
            width: 100,
        });
        await waitUntilReady();
        expect(lastFrame({ allowEmpty: true })).toBe('');
        unmount();
    });
    it.each([
        [[{ id: 'w1', message: 'Warning 1', priority: WarningPriority.High }]],
        [
            [
                { id: 'w1', message: 'Warning 1', priority: WarningPriority.High },
                { id: 'w2', message: 'Warning 2', priority: WarningPriority.High },
            ],
        ],
    ])('renders startup warnings: %s', async (warnings) => {
        const appState = {
            startupWarnings: warnings,
            version: '1.0.0',
        };
        mockUseAppContext.mockReturnValue(appState);
        const { lastFrame, waitUntilReady, unmount } = renderWithProviders(_jsx(Notifications, {}), {
            appState,
            settings,
            width: 100,
        });
        await waitUntilReady();
        const output = lastFrame();
        warnings.forEach((warning) => {
            expect(output).toContain(warning.message);
        });
        unmount();
    });
    it('increments show count for low priority warnings', async () => {
        const warnings = [
            { id: 'low-1', message: 'Low priority 1', priority: WarningPriority.Low },
        ];
        const appState = {
            startupWarnings: warnings,
            version: '1.0.0',
        };
        mockUseAppContext.mockReturnValue(appState);
        const { waitUntilReady, unmount } = renderWithProviders(_jsx(Notifications, {}), {
            appState,
            settings,
            width: 100,
        });
        await waitUntilReady();
        expect(persistentStateMock.set).toHaveBeenCalledWith('startupWarningCounts', { 'low-1': 1 });
        unmount();
    });
    it('filters out low priority warnings that exceeded max show count', async () => {
        const warnings = [
            { id: 'low-1', message: 'Low priority 1', priority: WarningPriority.Low },
            {
                id: 'high-1',
                message: 'High priority 1',
                priority: WarningPriority.High,
            },
        ];
        const appState = {
            startupWarnings: warnings,
            version: '1.0.0',
        };
        mockUseAppContext.mockReturnValue(appState);
        persistentStateMock.setData({
            startupWarningCounts: { 'low-1': 3 },
        });
        const { lastFrame, waitUntilReady, unmount } = renderWithProviders(_jsx(Notifications, {}), {
            appState,
            settings,
            width: 100,
        });
        await waitUntilReady();
        const output = lastFrame();
        expect(output).not.toContain('Low priority 1');
        expect(output).toContain('High priority 1');
        unmount();
    });
    it('dismisses warnings on keypress', async () => {
        const warnings = [
            {
                id: 'high-1',
                message: 'High priority 1',
                priority: WarningPriority.High,
            },
        ];
        const appState = {
            startupWarnings: warnings,
            version: '1.0.0',
        };
        mockUseAppContext.mockReturnValue(appState);
        const { lastFrame, stdin, waitUntilReady, unmount } = renderWithProviders(_jsx(Notifications, {}), {
            appState,
            settings,
            width: 100,
        });
        await waitUntilReady();
        expect(lastFrame()).toContain('High priority 1');
        await act(async () => {
            stdin.write('a');
        });
        await waitUntilReady();
        expect(lastFrame({ allowEmpty: true })).not.toContain('High priority 1');
        unmount();
    });
    it('renders init error', async () => {
        const uiState = {
            initError: 'Something went wrong',
            streamingState: 'idle',
            updateInfo: null,
        };
        mockUseUIState.mockReturnValue(uiState);
        const { lastFrame, waitUntilReady, unmount } = renderWithProviders(_jsx(Notifications, {}), {
            uiState,
            settings,
            width: 100,
        });
        await waitUntilReady();
        expect(lastFrame()).toMatchSnapshot();
        unmount();
    });
    it('does not render init error when streaming', async () => {
        const uiState = {
            initError: 'Something went wrong',
            streamingState: 'responding',
            updateInfo: null,
        };
        mockUseUIState.mockReturnValue(uiState);
        const { lastFrame, waitUntilReady, unmount } = renderWithProviders(_jsx(Notifications, {}), {
            uiState,
            settings,
            width: 100,
        });
        await waitUntilReady();
        expect(lastFrame({ allowEmpty: true })).toBe('');
        unmount();
    });
    it('renders update notification', async () => {
        const uiState = {
            initError: null,
            streamingState: 'idle',
            updateInfo: { message: 'Update available' },
        };
        mockUseUIState.mockReturnValue(uiState);
        const { lastFrame, waitUntilReady, unmount } = renderWithProviders(_jsx(Notifications, {}), {
            uiState,
            settings,
            width: 100,
        });
        await waitUntilReady();
        expect(lastFrame()).toMatchSnapshot();
        unmount();
    });
    it('renders screen reader nudge when enabled and not seen (no legacy file)', async () => {
        mockUseIsScreenReaderEnabled.mockReturnValue(true);
        persistentStateMock.setData({ hasSeenScreenReaderNudge: false });
        mockFsAccess.mockRejectedValue(new Error('No legacy file'));
        const { lastFrame, waitUntilReady, unmount } = renderWithProviders(_jsx(Notifications, {}), {
            settings,
            width: 100,
        });
        await waitUntilReady();
        expect(lastFrame()).toContain('screen reader-friendly view');
        expect(persistentStateMock.set).toHaveBeenCalledWith('hasSeenScreenReaderNudge', true);
        expect(lastFrame()).toMatchSnapshot();
        unmount();
    });
    it('migrates legacy screen reader nudge file', async () => {
        mockUseIsScreenReaderEnabled.mockReturnValue(true);
        persistentStateMock.setData({ hasSeenScreenReaderNudge: undefined });
        mockFsAccess.mockResolvedValue(undefined);
        const { waitUntilReady, unmount } = renderWithProviders(_jsx(Notifications, {}), {
            settings,
            width: 100,
        });
        await act(async () => {
            await waitUntilReady();
            await waitFor(() => {
                expect(persistentStateMock.set).toHaveBeenCalledWith('hasSeenScreenReaderNudge', true);
                expect(mockFsUnlink).toHaveBeenCalled();
            });
        });
        unmount();
    });
    it('does not render screen reader nudge when already seen in persistent state', async () => {
        mockUseIsScreenReaderEnabled.mockReturnValue(true);
        persistentStateMock.setData({ hasSeenScreenReaderNudge: true });
        const { lastFrame, waitUntilReady, unmount } = renderWithProviders(_jsx(Notifications, {}), {
            settings,
            width: 100,
        });
        await waitUntilReady();
        expect(lastFrame({ allowEmpty: true })).toBe('');
        expect(persistentStateMock.set).not.toHaveBeenCalled();
        unmount();
    });
});
//# sourceMappingURL=Notifications.test.js.map