/// <reference types="jest" />
import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';
import { AsyncLockManager } from '../src/core/lock';
import { TransactionManager } from '../src/core/transaction';

describe('System Vulnerability Tests', () => {
    let testDir: string;

    beforeEach(() => {
        testDir = path.join(os.tmpdir(), `g1-vulnerability-test-${Date.now()}`);
        if (!fs.existsSync(testDir)) {
            fs.mkdirSync(testDir, { recursive: true });
        }
    });

    afterEach(() => {
        if (fs.existsSync(testDir)) {
            fs.rmSync(testDir, { recursive: true, force: true });
        }
    });

    test('AsyncLockManager should prevent race conditions on the same file', async () => {
        const lockManager = new AsyncLockManager();
        const testFile = path.join(testDir, 'race_condition.txt');
        fs.writeFileSync(testFile, '0');

        // Simulate 10 concurrent increments
        const tasks = Array.from({ length: 10 }).map(async (_, i) => {
            const release = await lockManager.acquire(testFile);
            try {
                const current = parseInt(fs.readFileSync(testFile, 'utf-8'));
                // Artificial delay to increase race condition probability
                await new Promise(r => setTimeout(r, 10));
                fs.writeFileSync(testFile, (current + 1).toString());
            } finally {
                release();
            }
        });

        await Promise.all(tasks);

        const finalValue = fs.readFileSync(testFile, 'utf-8');
        expect(finalValue).toBe('10'); // If race condition occurs, it will be < 10
    });

    test('TransactionManager should support external verification hooks', () => {
        const tm = new TransactionManager();
        tm.begin();
        
        tm.recordExternalAction('DB_COMMIT', true);
        tm.recordExternalAction('API_PUSH', true);
        
        expect(tm.isFullyVerified()).toBe(true);

        tm.recordExternalAction('WIKI_SYNC', false);
        expect(tm.isFullyVerified()).toBe(false);
    });
});
