// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import "forge-std/Test.sol";
import { ThresholdConsensusV3 } from "../../contracts/consensus/ThresholdConsensusV3.sol";

contract OracleAttestorV3Test is Test {
    address internal owner = address(0xBEEF);
    address internal attesterA = address(0xA11);
    address internal attesterB = address(0xB22);
    ThresholdConsensusV3 internal consensus;

    function setUp() public {
        consensus = new ThresholdConsensusV3(owner, 2);
        vm.startPrank(owner);
        consensus.setAttester(attesterA, true);
        consensus.setAttester(attesterB, true);
        vm.stopPrank();
    }

    function test_thresholdFinalizationRejectsDuplicateExpiryAndConflict() external {
        ThresholdConsensusV3.Claim memory claim = ThresholdConsensusV3.Claim({
            schema: keccak256("schema"),
            subject: keccak256("subject"),
            nonce: 9,
            expiresAt: uint64(block.timestamp + 1 days),
            settlementSnapshot: keccak256("snapshot"),
            outcome: keccak256("outcome")
        });
        vm.prank(attesterA);
        consensus.attest(claim);
        vm.prank(attesterA);
        vm.expectRevert(ThresholdConsensusV3.DuplicateVote.selector);
        consensus.attest(claim);
        ThresholdConsensusV3.Claim memory conflict = ThresholdConsensusV3.Claim({
            schema: claim.schema,
            subject: claim.subject,
            nonce: claim.nonce,
            expiresAt: claim.expiresAt,
            settlementSnapshot: claim.settlementSnapshot,
            outcome: keccak256("other")
        });
        vm.prank(attesterB);
        vm.expectRevert(ThresholdConsensusV3.ConflictingClaim.selector);
        consensus.attest(conflict);
        vm.prank(attesterB);
        consensus.attest(claim);
        assertTrue(
            consensus.isFinalized(claim.schema, claim.subject, claim.nonce, claim.settlementSnapshot, claim.outcome)
        );
        vm.warp(block.timestamp + 2 days);
        claim.nonce = 10;
        vm.prank(attesterA);
        vm.expectRevert(ThresholdConsensusV3.ExpiredClaim.selector);
        consensus.attest(claim);
    }
}
