import { test, describe } from 'node:test';
import { strict as assert } from 'node:assert';

describe('Tests Edge Cases Basiques', () => {
    describe('JSON et Données', () => {
        test('JSON malformé', () => {
            const malformedJson = '{"name": "incomplete"';

            try {
                JSON.parse(malformedJson);
                assert.fail('Should have thrown');
            } catch (error) {
                assert.ok(error instanceof SyntaxError);
            }
        });

        test('Unicode et caractères spéciaux', () => {
            const text = "Café 🚀 测试";
            const jsonString = JSON.stringify({text});
            const parsed = JSON.parse(jsonString);
            assert.equal(parsed.text, text);
        });

        test('Références circulaires', () => {
            const obj = {name: "test"};
            obj.self = obj;

            try {
                JSON.stringify(obj);
                assert.fail('Should have thrown');
            } catch (error) {
                assert.ok(error.message.includes('circular'));
            }
        });
    });

    describe('APIs manquantes', () => {
        test('fetch manquant', () => {
            const original = global.fetch;
            delete global.fetch;

            try {
                fetch('http://test.com');
                assert.fail('Should have thrown');
            } catch (error) {
                assert.ok(error.name === 'ReferenceError');
            } finally {
                global.fetch = original;
            }
        });

        test('localStorage manquant', () => {
            const original = global.localStorage;
            delete global.localStorage;

            try {
                localStorage.setItem('test', 'value');
                assert.fail('Should have thrown');
            } catch (error) {
                assert.ok(error.name === 'ReferenceError');
            } finally {
                global.localStorage = original;
            }
        });
    });

    describe('Sécurité', () => {
        test('Échappement XSS', () => {
            const malicious = '<script>alert("xss")</script>';
            const escaped = malicious
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;');

            assert.equal(escaped, '&lt;script&gt;alert("xss")&lt;/script&gt;');
            assert.ok(!escaped.includes('<script>'));
        });

        test('URLs dangereuses', () => {
            const dangerousUrls = [
                'javascript:alert(1)',
                'data:text/html,<script>alert(1)</script>'
            ];

            for (const url of dangerousUrls) {
                try {
                    const urlObj = new URL(url);
                    assert.ok(!['http:', 'https:'].includes(urlObj.protocol));
                } catch (error) {
                    // URL invalide - acceptable
                    assert.ok(error instanceof TypeError);
                }
            }
        });
    });

    describe('Performance', () => {
        test('Grandes données', () => {
            const largeArray = new Array(10000).fill('test');
            assert.equal(largeArray.length, 10000);
            assert.equal(largeArray[0], 'test');
        });

        test('Chaînes longues', () => {
            const longString = 'x'.repeat(100000);
            assert.equal(longString.length, 100000);
            assert.equal(longString[0], 'x');
        });

        test('Calculs rapides', () => {
            const start = Date.now();
            let result = 0;
            for (let i = 0; i < 10000; i++) {
                result += Math.sqrt(i);
            }
            const end = Date.now();

            assert.ok(result > 0);
            assert.ok(end - start < 1000); // Moins d'1 seconde
        });
    });

    describe('Concurrence', () => {
        test('Promises parallèles', async () => {
            const promises = [];
            for (let i = 0; i < 5; i++) {
                promises.push(
                    new Promise(resolve =>
                        setTimeout(() => resolve(i), 10)
                    )
                );
            }

            const results = await Promise.all(promises);
            assert.equal(results.length, 5);
            assert.ok(results.includes(0));
            assert.ok(results.includes(4));
        });

        test('Race condition simple', async () => {
            let counter = 0;

            const increment = async () => {
                const current = counter;
                await new Promise(resolve => setTimeout(resolve, 1));
                counter = current + 1;
            };

            await Promise.all([increment(), increment()]);
            assert.ok(counter >= 1 && counter <= 2);
        });
    });
});