/**
 * Skills Registry Module
 *
 * A ClawHub-like registry for discovering, installing, and managing skills.
 */
import { EventEmitter } from 'events';
import * as crypto from 'crypto';
export const DEFAULT_REGISTRY_CONFIG = {
    registryUrl: 'https://registry.codebuddy.dev',
    installDir: '~/.codebuddy/skills',
    autoUpdate: true,
    updateCheckIntervalMs: 24 * 60 * 60 * 1000, // Daily
    cacheTTLMs: 60 * 60 * 1000, // 1 hour
    allowUnverified: true,
};
// ============================================================================
// Skills Registry
// ============================================================================
export class SkillsRegistry extends EventEmitter {
    config;
    installedSkills = new Map();
    searchCache = new Map();
    updateCheckTimer = null;
    // Mock registry data
    mockRegistry = [];
    constructor(config = {}) {
        super();
        this.config = { ...DEFAULT_REGISTRY_CONFIG, ...config };
        this.initializeMockRegistry();
    }
    initializeMockRegistry() {
        this.mockRegistry = [
            {
                name: '@codebuddy/git-workflow',
                displayName: 'Git Workflow',
                description: 'Enhanced Git operations with smart commit messages and PR creation',
                latestVersion: '2.1.0',
                author: 'Code Buddy Team',
                downloads: 15420,
                stars: 342,
                verified: true,
                category: 'development',
                keywords: ['git', 'workflow', 'commit', 'pr'],
                updatedAt: new Date('2025-01-15'),
            },
            {
                name: '@codebuddy/code-review',
                displayName: 'Code Review Assistant',
                description: 'AI-powered code review with suggestions and best practices',
                latestVersion: '1.5.2',
                author: 'Code Buddy Team',
                downloads: 12850,
                stars: 289,
                verified: true,
                category: 'development',
                keywords: ['review', 'quality', 'suggestions'],
                updatedAt: new Date('2025-01-10'),
            },
            {
                name: '@codebuddy/test-generator',
                displayName: 'Test Generator',
                description: 'Automatically generate unit tests for your code',
                latestVersion: '1.2.0',
                author: 'Code Buddy Team',
                downloads: 9840,
                stars: 215,
                verified: true,
                category: 'development',
                keywords: ['test', 'unit', 'coverage', 'jest'],
                updatedAt: new Date('2025-01-08'),
            },
            {
                name: '@community/slack-notifier',
                displayName: 'Slack Notifier',
                description: 'Send notifications to Slack channels',
                latestVersion: '0.8.3',
                author: 'Community',
                downloads: 5620,
                stars: 98,
                verified: false,
                category: 'communication',
                keywords: ['slack', 'notification', 'messaging'],
                updatedAt: new Date('2024-12-20'),
            },
            {
                name: '@community/data-transformer',
                displayName: 'Data Transformer',
                description: 'Transform data between formats (JSON, CSV, YAML, etc.)',
                latestVersion: '1.0.1',
                author: 'DataWizard',
                downloads: 4280,
                stars: 76,
                verified: false,
                category: 'data',
                keywords: ['json', 'csv', 'yaml', 'transform', 'convert'],
                updatedAt: new Date('2024-12-15'),
            },
            {
                name: '@security/vault-manager',
                displayName: 'Vault Manager',
                description: 'Securely manage secrets and credentials',
                latestVersion: '2.0.0',
                author: 'Security Team',
                downloads: 7890,
                stars: 156,
                verified: true,
                category: 'security',
                keywords: ['vault', 'secrets', 'credentials', 'security'],
                updatedAt: new Date('2025-01-05'),
            },
        ];
    }
    // ============================================================================
    // Search & Discovery
    // ============================================================================
    /**
     * Search for skills
     */
    async search(query, options) {
        // Check cache
        const cacheKey = JSON.stringify({ query, options });
        const cached = this.searchCache.get(cacheKey);
        if (cached && Date.now() - cached.timestamp < this.config.cacheTTLMs) {
            return cached.results;
        }
        // Simulate API call
        await new Promise(resolve => setTimeout(resolve, 100));
        let results = [...this.mockRegistry];
        // Filter by query
        if (query) {
            const lowerQuery = query.toLowerCase();
            results = results.filter(skill => skill.name.toLowerCase().includes(lowerQuery) ||
                skill.displayName.toLowerCase().includes(lowerQuery) ||
                skill.description.toLowerCase().includes(lowerQuery) ||
                skill.keywords.some(k => k.toLowerCase().includes(lowerQuery)));
        }
        // Filter by category
        if (options?.category) {
            results = results.filter(skill => skill.category === options.category);
        }
        // Filter by verified
        if (options?.verified !== undefined) {
            results = results.filter(skill => skill.verified === options.verified);
        }
        // Pagination
        const offset = options?.offset || 0;
        const limit = options?.limit || 20;
        results = results.slice(offset, offset + limit);
        // Cache results
        this.searchCache.set(cacheKey, { results, timestamp: Date.now() });
        this.emit('search-complete', results);
        return results;
    }
    /**
     * Get skill details
     */
    async getSkillDetails(name) {
        await new Promise(resolve => setTimeout(resolve, 50));
        return this.mockRegistry.find(s => s.name === name) || null;
    }
    /**
     * Get skill versions
     */
    async getVersions(name) {
        await new Promise(resolve => setTimeout(resolve, 50));
        const skill = this.mockRegistry.find(s => s.name === name);
        if (!skill)
            return [];
        // Mock versions
        return [
            {
                version: skill.latestVersion,
                releasedAt: skill.updatedAt,
                downloadUrl: `${this.config.registryUrl}/packages/${name}/${skill.latestVersion}`,
                checksum: crypto.randomBytes(32).toString('hex'),
                size: 102400,
            },
            {
                version: '1.0.0',
                releasedAt: new Date('2024-01-01'),
                downloadUrl: `${this.config.registryUrl}/packages/${name}/1.0.0`,
                checksum: crypto.randomBytes(32).toString('hex'),
                size: 98304,
            },
        ];
    }
    /**
     * Get featured/popular skills
     */
    async getFeatured() {
        return this.mockRegistry
            .filter(s => s.verified)
            .sort((a, b) => b.downloads - a.downloads)
            .slice(0, 5);
    }
    /**
     * Get skills by category
     */
    async getByCategory(category) {
        return this.search('', { category });
    }
    // ============================================================================
    // Installation
    // ============================================================================
    /**
     * Install a skill
     */
    async install(name, version) {
        // Check if already installed
        if (this.installedSkills.has(name)) {
            throw new Error(`Skill ${name} is already installed`);
        }
        // Get skill details
        const details = await this.getSkillDetails(name);
        if (!details) {
            throw new Error(`Skill ${name} not found in registry`);
        }
        // Check if unverified is allowed
        if (!details.verified && !this.config.allowUnverified) {
            throw new Error(`Skill ${name} is not verified. Enable allowUnverified to install.`);
        }
        // Simulate download
        await new Promise(resolve => setTimeout(resolve, 200));
        const installed = {
            manifest: {
                name: details.name,
                version: version || details.latestVersion,
                displayName: details.displayName,
                description: details.description,
                author: { name: details.author },
                license: 'MIT',
                keywords: details.keywords,
                main: 'index.js',
                category: details.category,
                verified: details.verified,
            },
            installPath: `${this.config.installDir}/${name}`,
            installedAt: new Date(),
            enabled: true,
        };
        this.installedSkills.set(name, installed);
        this.emit('skill-install', installed);
        return installed;
    }
    /**
     * Uninstall a skill
     */
    async uninstall(name) {
        if (!this.installedSkills.has(name)) {
            return false;
        }
        // Simulate cleanup
        await new Promise(resolve => setTimeout(resolve, 50));
        this.installedSkills.delete(name);
        this.emit('skill-uninstall', name);
        return true;
    }
    /**
     * Update a skill
     */
    async update(name, version) {
        const installed = this.installedSkills.get(name);
        if (!installed) {
            return null;
        }
        const details = await this.getSkillDetails(name);
        if (!details) {
            return null;
        }
        const targetVersion = version || details.latestVersion;
        if (installed.manifest.version === targetVersion) {
            return installed; // Already up to date
        }
        const oldVersion = installed.manifest.version;
        // Simulate update
        await new Promise(resolve => setTimeout(resolve, 150));
        installed.manifest.version = targetVersion;
        installed.updatedAt = new Date();
        this.emit('skill-update', installed, oldVersion);
        return installed;
    }
    /**
     * Update all skills
     */
    async updateAll() {
        const updated = [];
        for (const [name, _installed] of this.installedSkills) {
            const result = await this.update(name);
            if (result) {
                updated.push(result);
            }
        }
        return updated;
    }
    // ============================================================================
    // Installed Skills Management
    // ============================================================================
    /**
     * Get installed skills
     */
    getInstalled() {
        return Array.from(this.installedSkills.values());
    }
    /**
     * Get installed skill by name
     */
    getInstalledSkill(name) {
        return this.installedSkills.get(name);
    }
    /**
     * Check if skill is installed
     */
    isInstalled(name) {
        return this.installedSkills.has(name);
    }
    /**
     * Enable a skill
     */
    enable(name) {
        const skill = this.installedSkills.get(name);
        if (!skill)
            return false;
        skill.enabled = true;
        this.emit('skill-enable', name);
        return true;
    }
    /**
     * Disable a skill
     */
    disable(name) {
        const skill = this.installedSkills.get(name);
        if (!skill)
            return false;
        skill.enabled = false;
        this.emit('skill-disable', name);
        return true;
    }
    /**
     * Get enabled skills
     */
    getEnabled() {
        return Array.from(this.installedSkills.values()).filter(s => s.enabled);
    }
    /**
     * Configure a skill
     */
    configure(name, config) {
        const skill = this.installedSkills.get(name);
        if (!skill)
            return false;
        skill.config = { ...skill.config, ...config };
        return true;
    }
    // ============================================================================
    // Update Checking
    // ============================================================================
    /**
     * Check for updates
     */
    async checkForUpdates() {
        const updates = [];
        for (const [name, installed] of this.installedSkills) {
            const details = await this.getSkillDetails(name);
            if (details && details.latestVersion !== installed.manifest.version) {
                updates.push({
                    name,
                    current: installed.manifest.version,
                    latest: details.latestVersion,
                });
                this.emit('update-available', name, installed.manifest.version, details.latestVersion);
            }
        }
        return updates;
    }
    /**
     * Start auto-update checking
     */
    startAutoUpdateCheck() {
        if (this.updateCheckTimer)
            return;
        this.updateCheckTimer = setInterval(() => {
            this.checkForUpdates().catch(error => {
                this.emit('error', error instanceof Error ? error : new Error(String(error)));
            });
        }, this.config.updateCheckIntervalMs);
    }
    /**
     * Stop auto-update checking
     */
    stopAutoUpdateCheck() {
        if (this.updateCheckTimer) {
            clearInterval(this.updateCheckTimer);
            this.updateCheckTimer = null;
        }
    }
    // ============================================================================
    // Configuration
    // ============================================================================
    /**
     * Get configuration
     */
    getConfig() {
        return { ...this.config };
    }
    /**
     * Update configuration
     */
    updateConfig(config) {
        this.config = { ...this.config, ...config };
    }
    /**
     * Clear search cache
     */
    clearCache() {
        this.searchCache.clear();
    }
    /**
     * Get statistics
     */
    getStats() {
        return {
            installedCount: this.installedSkills.size,
            enabledCount: this.getEnabled().length,
            cacheEntries: this.searchCache.size,
            isAutoUpdating: this.updateCheckTimer !== null,
        };
    }
    /**
     * Shutdown
     */
    shutdown() {
        this.stopAutoUpdateCheck();
        this.clearCache();
        this.installedSkills.clear();
    }
}
// ============================================================================
// Singleton
// ============================================================================
let skillsRegistryInstance = null;
export function getSkillsRegistry(config) {
    if (!skillsRegistryInstance) {
        skillsRegistryInstance = new SkillsRegistry(config);
    }
    return skillsRegistryInstance;
}
export function resetSkillsRegistry() {
    if (skillsRegistryInstance) {
        skillsRegistryInstance.shutdown();
        skillsRegistryInstance = null;
    }
}
//# sourceMappingURL=index.js.map