<?php

declare(strict_types=1);

use App\Framework\LiveComponents\ValueObjects\ChunkHash;

describe('ChunkHash Value Object', function () {
    it('creates hash from chunk data', function () {
        $data = 'test chunk data';
        $hash = ChunkHash::fromData($data);

        expect($hash->toString())->toBeString();
        expect(strlen($hash->toString()))->toBe(64); // SHA-256 = 64 hex characters
    });

    it('creates hash from string', function () {
        $hashString = hash('sha256', 'test data');
        $hash = ChunkHash::fromString($hashString);

        expect($hash->toString())->toBe($hashString);
    });

    it('creates hash from file', function () {
        $tempFile = tempnam(sys_get_temp_dir(), 'chunk_test_');
        file_put_contents($tempFile, 'test file content');

        try {
            $hash = ChunkHash::fromFile($tempFile);

            expect($hash->toString())->toBeString();
            expect(strlen($hash->toString()))->toBe(64);
        } finally {
            unlink($tempFile);
        }
    });

    it('verifies chunk data correctly', function () {
        $data = 'test chunk data';
        $hash = ChunkHash::fromData($data);

        expect($hash->verify($data))->toBeTrue();
        expect($hash->verify('different data'))->toBeFalse();
    });

    it('verifies file correctly', function () {
        $tempFile = tempnam(sys_get_temp_dir(), 'chunk_test_');
        file_put_contents($tempFile, 'test file content');

        try {
            $hash = ChunkHash::fromFile($tempFile);

            expect($hash->verifyFile($tempFile))->toBeTrue();

            // Modify file and verify again
            file_put_contents($tempFile, 'modified content');
            expect($hash->verifyFile($tempFile))->toBeFalse();
        } finally {
            unlink($tempFile);
        }
    });

    it('compares hashes for equality', function () {
        $data = 'test data';
        $hash1 = ChunkHash::fromData($data);
        $hash2 = ChunkHash::fromData($data);
        $hash3 = ChunkHash::fromData('different data');

        expect($hash1->equals($hash2))->toBeTrue();
        expect($hash1->equals($hash3))->toBeFalse();
    });

    it('converts to string', function () {
        $data = 'test data';
        $hash = ChunkHash::fromData($data);

        $expectedHash = hash('sha256', $data);
        expect($hash->toString())->toBe($expectedHash);
        expect((string) $hash)->toBe($expectedHash);
    });

    it('produces consistent hashes for same data', function () {
        $data = 'consistent data';

        $hash1 = ChunkHash::fromData($data);
        $hash2 = ChunkHash::fromData($data);

        expect($hash1->toString())->toBe($hash2->toString());
    });

    it('produces different hashes for different data', function () {
        $hash1 = ChunkHash::fromData('data 1');
        $hash2 = ChunkHash::fromData('data 2');

        $hash1String = $hash1->toString();
        $hash2String = $hash2->toString();
        expect($hash1String === $hash2String)->toBeFalse();
    });

    it('exposes underlying Hash value object', function () {
        $hash = ChunkHash::fromData('test');

        expect($hash->getHash())->toBeInstanceOf(\App\Framework\Core\ValueObjects\Hash::class);
    });
});
