// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {Test} from "forge-std/Test.sol";
import {ReserveCommitmentStore} from "../../contracts/hybx-omnl/ReserveCommitmentStore.sol";

contract ReserveAttestationTest is Test {
    uint256 internal constant PK = 0xA11CE;

    ReserveCommitmentStore public store;
    bytes32 internal constant LINE = keccak256("ATTEST_LINE");

    function setUp() public {
        store = new ReserveCommitmentStore(address(this));
        address signer = vm.addr(PK);
        store.setAttestationSigner(signer, true);
        store.setAttestationThreshold(1);
    }

    function testCommitReserveAttested() public {
        uint256 R = 1_000_000;
        uint256 validUntil = block.timestamp + 1 days;
        bytes32 ev = bytes32(uint256(7));
        bytes32 mr = bytes32(uint256(8));
        uint256 nonce = 0;

        bytes32 digest = keccak256(
            abi.encode(
                store.ATTESTATION_TYPEHASH(),
                block.chainid,
                address(store),
                LINE,
                R,
                validUntil,
                ev,
                mr,
                nonce
            )
        );
        bytes32 ethSignedMessageHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", digest));
        (uint8 v, bytes32 r, bytes32 s) = vm.sign(PK, ethSignedMessageHash);
        bytes[] memory sigs = new bytes[](1);
        sigs[0] = abi.encodePacked(r, s, v);

        vm.prank(address(0xBEEF));
        store.commitReserveAttested(LINE, R, validUntil, ev, mr, nonce, sigs);

        ReserveCommitmentStore.Commitment memory c = store.getCommitment(LINE);
        assertEq(c.R, R);
        assertEq(c.merkleRoot, mr);
        assertEq(store.lineAttestationNonce(LINE), 1);
    }
}
