/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
import * as fs from 'node:fs';
import * as path from 'node:path';
import * as os from 'node:os';
import { ExtensionManager } from './extension-manager.js';
import { loadSettings } from './settings.js';
import { createExtension } from '../test-utils/createExtension.js';
import { EXTENSIONS_DIRECTORY_NAME } from './extensions/variables.js';
import { coreEvents } from '@google/gemini-cli-core';
const mockHomedir = vi.hoisted(() => vi.fn());
vi.mock('os', async (importOriginal) => {
    const mockedOs = await importOriginal();
    return {
        ...mockedOs,
        homedir: mockHomedir,
    };
});
describe('ExtensionManager skills validation', () => {
    let tempHomeDir;
    let tempWorkspaceDir;
    let userExtensionsDir;
    let extensionManager;
    beforeEach(() => {
        tempHomeDir = fs.mkdtempSync(path.join(os.tmpdir(), 'gemini-cli-skills-test-home-'));
        tempWorkspaceDir = fs.mkdtempSync(path.join(tempHomeDir, 'gemini-cli-skills-test-workspace-'));
        userExtensionsDir = path.join(tempHomeDir, EXTENSIONS_DIRECTORY_NAME);
        fs.mkdirSync(userExtensionsDir, { recursive: true });
        mockHomedir.mockReturnValue(tempHomeDir);
        extensionManager = new ExtensionManager({
            workspaceDir: tempWorkspaceDir,
            requestConsent: vi.fn().mockResolvedValue(true),
            requestSetting: vi.fn().mockResolvedValue(''),
            settings: loadSettings(tempWorkspaceDir).merged,
        });
        vi.spyOn(coreEvents, 'emitFeedback');
    });
    afterEach(() => {
        fs.rmSync(tempHomeDir, { recursive: true, force: true });
        vi.restoreAllMocks();
    });
    it('should emit a warning during install if skills directory is not empty but no skills are loaded', async () => {
        const sourceExtDir = createExtension({
            extensionsDir: tempHomeDir,
            name: 'skills-ext',
            version: '1.0.0',
        });
        const skillsDir = path.join(sourceExtDir, 'skills');
        fs.mkdirSync(skillsDir);
        fs.writeFileSync(path.join(skillsDir, 'not-a-skill.txt'), 'hello');
        await extensionManager.loadExtensions();
        const extension = await extensionManager.installOrUpdateExtension({
            source: sourceExtDir,
            type: 'local',
        });
        expect(extension.name).toBe('skills-ext');
        expect(coreEvents.emitFeedback).toHaveBeenCalledWith('warning', expect.stringContaining('Failed to load skills from'));
    });
    it('should emit a warning during load if skills directory is not empty but no skills are loaded', async () => {
        const extDir = createExtension({
            extensionsDir: userExtensionsDir,
            name: 'load-skills-ext',
            version: '1.0.0',
        });
        const skillsDir = path.join(extDir, 'skills');
        fs.mkdirSync(skillsDir);
        fs.writeFileSync(path.join(skillsDir, 'not-a-skill.txt'), 'hello');
        await extensionManager.loadExtensions();
        expect(coreEvents.emitFeedback).toHaveBeenCalledWith('warning', expect.stringContaining('Failed to load skills from'));
        expect(coreEvents.emitFeedback).toHaveBeenCalledWith('warning', expect.stringContaining('The directory is not empty but no valid skills were discovered'));
    });
    it('should succeed if skills are correctly loaded', async () => {
        const sourceExtDir = createExtension({
            extensionsDir: tempHomeDir,
            name: 'good-skills-ext',
            version: '1.0.0',
        });
        const skillsDir = path.join(sourceExtDir, 'skills');
        const skillSubdir = path.join(skillsDir, 'test-skill');
        fs.mkdirSync(skillSubdir, { recursive: true });
        fs.writeFileSync(path.join(skillSubdir, 'SKILL.md'), '---\nname: test-skill\ndescription: test desc\n---\nbody');
        await extensionManager.loadExtensions();
        const extension = await extensionManager.installOrUpdateExtension({
            source: sourceExtDir,
            type: 'local',
        });
        expect(extension.skills).toHaveLength(1);
        expect(extension.skills[0].name).toBe('test-skill');
        // It might be called for other reasons during startup, but shouldn't be called for our skills loading success
        // Actually, it shouldn't be called with our warning message
        expect(coreEvents.emitFeedback).not.toHaveBeenCalledWith('warning', expect.stringContaining('Failed to load skills from'));
    });
});
//# sourceMappingURL=extension-manager-skills.test.js.map