"""
Unit tests for Blockchain Integrity

Tests signature verification, hash chaining, and tamper detection.
"""

import pytest
import json
import time
from altrus.core.ledger.blockchain import BlockchainLedger
from altrus.core.ledger.block import Block
from altrus.core.ledger.crypto import sign_block_data

@pytest.fixture
def ledger(tmp_path):
    return BlockchainLedger(storage_dir=tmp_path)

def test_genesis_block(ledger):
    chain = ledger.get_chain()
    assert len(chain) == 1
    assert chain[0].index == 0
    assert chain[0].previous_hash == "0"
    assert chain[0].verify_signature()

def test_add_block_integrity(ledger):
    ledger.add_block({"test": "data"})
    ledger.add_block({"more": "data"})

    assert ledger.verify_integrity()
    assert len(ledger.get_chain()) == 3

def test_tamper_detection(ledger):
    ledger.add_block({"test": "data"})
    chain = ledger.get_chain()

    # Tamper with block 1
    chain[1].data["test"] = "TAMPERED"

    # recalculate_hash is NOT called, so the hash link might still hold
    # but the block's own hash won't match its data
    assert not ledger.verify_integrity()

def test_signature_verification(ledger):
    block = ledger.add_block({"test": "data"})
    assert block.verify_signature()

    # Tamper with signature
    block.signature.signature = "invalid"
    assert not block.verify_signature()
    assert not ledger.verify_integrity()

def test_fork_resolution(ledger):
    ledger.add_block({"original": "chain"})
    original_chain = list(ledger.get_chain())

    # Create a longer valid chain
    longer_chain = []
    genesis = original_chain[0]
    longer_chain.append(genesis)

    prev_hash = genesis.hash
    for i in range(1, 4):
        data = {"longer": f"block {i}"}
        block = Block(index=i, previous_hash=prev_hash, data=data)
        block.signature = sign_block_data(json.dumps(data, sort_keys=True))
        block.hash = block.calculate_hash()
        longer_chain.append(block)
        prev_hash = block.hash

    resolved = ledger.handle_fork(longer_chain)
    assert resolved
    assert len(ledger.get_chain()) == 4
    assert ledger.verify_integrity()
