import { StorageManager } from '../../storage/storage-manager.js';
import crypto from 'crypto';
export class TestingStore {
    storageManager;
    moduleName = 'testing-framework';
    constructor(configManager) {
        this.storageManager = new StorageManager();
    }
    async initialize() {
        await this.storageManager.ensureStorageDirectories();
    }
    // Test Result Management
    async saveTestResult(result) {
        let history = [];
        try {
            history = await this.storageManager.loadData(this.moduleName, 'test-history.json') || [];
        }
        catch {
            // File doesn't exist yet
        }
        history.push(result);
        // Keep only last 100 test runs
        if (history.length > 100) {
            history = history.slice(-100);
        }
        await this.storageManager.saveData(this.moduleName, 'test-history.json', history);
    }
    async getTestHistory(limit) {
        try {
            const history = await this.storageManager.loadData(this.moduleName, 'test-history.json');
            if (limit && limit > 0) {
                return (history || []).slice(-limit);
            }
            return history || [];
        }
        catch {
            return [];
        }
    }
    async getLatestTestResult() {
        const history = await this.getTestHistory(1);
        return history.length > 0 ? history[0] : null;
    }
    // Coverage Management
    async saveCoverageData(coverage) {
        const filename = `coverage-${new Date().toISOString().split('T')[0]}.json`;
        await this.storageManager.saveData(this.moduleName, filename, coverage);
        // Also update latest coverage
        await this.storageManager.saveData(this.moduleName, 'coverage-latest.json', coverage);
    }
    async getLatestCoverage() {
        try {
            return await this.storageManager.loadData(this.moduleName, 'coverage-latest.json');
        }
        catch {
            return null;
        }
    }
    async getCoverageHistory(days = 30) {
        const history = [];
        const startDate = new Date();
        startDate.setDate(startDate.getDate() - days);
        // This is simplified - in a real implementation, you'd scan for coverage files
        // For now, just return the latest coverage if it exists
        const latest = await this.getLatestCoverage();
        if (latest) {
            history.push(latest);
        }
        return history;
    }
    // Flaky Test Detection
    async trackFlakyTest(testName, suiteName, passed) {
        let flakyTests = {};
        try {
            flakyTests = await this.storageManager.loadData(this.moduleName, 'flaky-tests.json') || {};
        }
        catch {
            // File doesn't exist yet
        }
        const key = `${suiteName}::${testName}`;
        if (!flakyTests[key]) {
            flakyTests[key] = {
                testId: crypto.randomUUID(),
                name: testName,
                suite: suiteName,
                failureRate: 0,
                recentResults: [],
                lastFailed: new Date().toISOString(),
                errorPatterns: [],
                testName,
                suiteName,
                firstSeen: new Date().toISOString(),
                lastSeen: new Date().toISOString(),
                failures: 0,
                passes: 0,
                totalRuns: 0,
                recentRuns: [],
            };
        }
        const test = flakyTests[key];
        test.lastSeen = new Date().toISOString();
        test.totalRuns++;
        if (passed) {
            test.passes++;
        }
        else {
            test.failures++;
        }
        test.failureRate = test.failures / test.totalRuns;
        // Track recent runs (last 10)
        test.recentRuns.push({
            passed,
            timestamp: new Date().toISOString(),
        });
        if (test.recentRuns.length > 10) {
            test.recentRuns = test.recentRuns.slice(-10);
        }
        await this.storageManager.saveData(this.moduleName, 'flaky-tests.json', flakyTests);
    }
    async getFlakyTests(threshold = 0.1) {
        try {
            const flakyTests = await this.storageManager.loadData(this.moduleName, 'flaky-tests.json');
            return Object.values(flakyTests || {})
                .filter(test => test.failureRate > threshold &&
                test.failureRate < (1 - threshold) &&
                test.totalRuns >= 5)
                .sort((a, b) => b.failureRate - a.failureRate);
        }
        catch {
            return [];
        }
    }
    // Test Baselines
    async setTestBaseline(name, baseline) {
        let baselines = {};
        try {
            baselines = await this.storageManager.loadData(this.moduleName, 'test-baselines.json') || {};
        }
        catch {
            // File doesn't exist yet
        }
        baselines[name] = baseline;
        await this.storageManager.saveData(this.moduleName, 'test-baselines.json', baselines);
    }
    async getTestBaseline(name) {
        try {
            const baselines = await this.storageManager.loadData(this.moduleName, 'test-baselines.json');
            return baselines[name] || null;
        }
        catch {
            return null;
        }
    }
    async getAllBaselines() {
        try {
            return await this.storageManager.loadData(this.moduleName, 'test-baselines.json') || {};
        }
        catch {
            return {};
        }
    }
    // Additional methods for testing-framework module
    async getTestHistoryForProject(projectId) {
        const history = await this.getTestHistory();
        const projectHistory = history.filter(r => r.projectId === projectId);
        // Calculate trends
        const trends = [];
        if (projectHistory.length >= 2) {
            const recent = projectHistory.slice(-10);
            const successRates = recent.map(r => r.summary.successRate);
            const avgSuccessRate = successRates.reduce((a, b) => a + b, 0) / successRates.length;
            const firstRate = successRates[0];
            const lastRate = successRates[successRates.length - 1];
            trends.push({
                metric: 'successRate',
                values: successRates.map((v, i) => ({ timestamp: recent[i].timestamp, value: v })),
                trend: lastRate > firstRate ? 'improving' : lastRate < firstRate ? 'degrading' : 'stable',
                changePercentage: ((lastRate - firstRate) / firstRate) * 100,
            });
        }
        return {
            projectId,
            results: projectHistory,
            baseline: projectHistory.find(r => r.tags?.includes('baseline')),
            trends,
            lastUpdated: new Date().toISOString(),
        };
    }
    async compareTestResults(baselineId, currentId) {
        const history = await this.getTestHistory();
        const baseline = history.find(r => r.id === baselineId);
        const current = history.find(r => r.id === currentId);
        if (!baseline || !current) {
            throw new Error('Test results not found');
        }
        const baselineTests = new Set(baseline.suites.flatMap(s => s.tests.map(t => `${s.name}::${t.name}`)));
        const currentTests = new Set(current.suites.flatMap(s => s.tests.map(t => `${s.name}::${t.name}`)));
        return {
            baseline,
            current,
            improvements: [],
            regressions: [],
            newTests: Array.from(currentTests).filter(t => !baselineTests.has(t)),
            removedTests: Array.from(baselineTests).filter(t => !currentTests.has(t)),
            coverageChange: {
                lines: (current.coverage?.lines.percentage || 0) - (baseline.coverage?.lines.percentage || 0),
                statements: (current.coverage?.statements.percentage || 0) - (baseline.coverage?.statements.percentage || 0),
                functions: (current.coverage?.functions.percentage || 0) - (baseline.coverage?.functions.percentage || 0),
                branches: (current.coverage?.branches.percentage || 0) - (baseline.coverage?.branches.percentage || 0),
            },
        };
    }
    async saveFlakyTests(tests) {
        await this.storageManager.saveData(this.moduleName, 'flaky-tests-report.json', {
            flakyTests: tests,
            timestamp: new Date().toISOString(),
        });
    }
    async setBaseline(resultId, projectId) {
        const history = await this.getTestHistory();
        const result = history.find(r => r.id === resultId);
        if (!result) {
            throw new Error('Test result not found');
        }
        // Add baseline tag
        if (!result.tags) {
            result.tags = [];
        }
        if (!result.tags.includes('baseline')) {
            result.tags.push('baseline');
        }
        // Update history
        await this.storageManager.saveData(this.moduleName, 'test-history.json', history);
    }
    async getTestResultById(id) {
        const history = await this.getTestHistory();
        return history.find(r => r.id === id) || null;
    }
    // Test History Analysis
    async getTestTrend(testName, days = 7) {
        const history = await this.getTestHistory();
        const startDate = new Date();
        startDate.setDate(startDate.getDate() - days);
        const trend = [];
        for (const result of history) {
            if (new Date(result.timestamp) < startDate)
                continue;
            const suite = result.suites.find(s => s.tests.some(t => t.name === testName));
            if (suite) {
                const test = suite.tests.find(t => t.name === testName);
                if (test) {
                    trend.push({
                        timestamp: result.timestamp,
                        passed: test.status === 'passed',
                        duration: test.duration,
                    });
                }
            }
        }
        return trend;
    }
    async getSuccessRate(days = 30) {
        const history = await this.getTestHistory();
        const startDate = new Date();
        startDate.setDate(startDate.getDate() - days);
        const recentRuns = history.filter(result => new Date(result.timestamp) >= startDate);
        if (recentRuns.length === 0)
            return 0;
        const successfulRuns = recentRuns.filter(result => result.summary.failed === 0).length;
        return (successfulRuns / recentRuns.length) * 100;
    }
    // Export/Import
    async exportTestData() {
        const [history, coverage, flakyTests, baselines,] = await Promise.all([
            this.getTestHistory(),
            this.getLatestCoverage(),
            this.storageManager.loadData(this.moduleName, 'flaky-tests.json').catch(() => ({})),
            this.getAllBaselines(),
        ]);
        return {
            testHistory: history,
            latestCoverage: coverage,
            flakyTests,
            testBaselines: baselines,
            exportedAt: new Date().toISOString(),
        };
    }
    async importTestData(data) {
        if (data.testHistory) {
            await this.storageManager.saveData(this.moduleName, 'test-history.json', data.testHistory);
        }
        if (data.latestCoverage) {
            await this.storageManager.saveData(this.moduleName, 'coverage-latest.json', data.latestCoverage);
        }
        if (data.flakyTests) {
            await this.storageManager.saveData(this.moduleName, 'flaky-tests.json', data.flakyTests);
        }
        if (data.testBaselines) {
            await this.storageManager.saveData(this.moduleName, 'test-baselines.json', data.testBaselines);
        }
    }
    // Cleanup
    async cleanupOldData(daysToKeep = 30) {
        let cleanedItems = 0;
        // Clean test history
        const history = await this.getTestHistory();
        const cutoffDate = new Date();
        cutoffDate.setDate(cutoffDate.getDate() - daysToKeep);
        const filteredHistory = history.filter(result => new Date(result.timestamp) > cutoffDate);
        if (filteredHistory.length < history.length) {
            await this.storageManager.saveData(this.moduleName, 'test-history.json', filteredHistory);
            cleanedItems += history.length - filteredHistory.length;
        }
        // Clean flaky test data that hasn't been seen recently
        const flakyTests = await this.storageManager.loadData(this.moduleName, 'flaky-tests.json').catch(() => ({}));
        const filteredFlakyTests = {};
        for (const [key, test] of Object.entries(flakyTests)) {
            if (new Date(test.lastSeen) > cutoffDate) {
                filteredFlakyTests[key] = test;
            }
            else {
                cleanedItems++;
            }
        }
        await this.storageManager.saveData(this.moduleName, 'flaky-tests.json', filteredFlakyTests);
        return cleanedItems;
    }
}
//# sourceMappingURL=store.js.map