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

import { Test } from "forge-std/Test.sol";
import { MultisigGovernanceV3 } from "../../contracts/governance/MultisigGovernanceV3.sol";
import {
    BasePilotAccessControllerV3,
    BasePilotAccessControllerCoreV3
} from "../../contracts/pilot/BasePilotAccessControllerV3.sol";
import { ThresholdConsensusV3 } from "../../contracts/consensus/ThresholdConsensusV3.sol";
import { DisputeRegistryV3 } from "../../contracts/disputes/DisputeRegistryV3.sol";
import { RewardProgramV3 } from "../../contracts/bonds/RewardProgramV3.sol";
import { SafeBondFactoryV3 } from "../../contracts/bonds/SafeBondFactoryV3.sol";

/// @notice Focused regression coverage for the read-only Base bootstrap.
/// @dev This is not an activation rehearsal: no attester, adjudicator,
/// design-partner, controller module, child bond, or value flow is configured.
contract BaseReadOnlyBootstrapV3Test is Test {
    uint256 internal constant TIMELOCK = 1 days;
    address internal constant SIGNER_A = address(0xA11CE);
    address internal constant SIGNER_B = address(0xB0B);
    address internal constant SIGNER_C = address(0xC0C);
    address internal constant SIGNER_D = address(0xD0D);
    address internal constant SIGNER_E = address(0xE0E);
    address internal constant GUARDIAN = address(0x600D);
    address internal constant PARTNER = address(0xD3516);

    MultisigGovernanceV3 internal governance;
    BasePilotAccessControllerV3 internal controller;
    ThresholdConsensusV3 internal consensus;
    DisputeRegistryV3 internal disputes;
    RewardProgramV3 internal rewards;
    SafeBondFactoryV3 internal factory;

    function setUp() external {
        vm.chainId(8453);
        address[] memory signers = new address[](5);
        signers[0] = SIGNER_A;
        signers[1] = SIGNER_B;
        signers[2] = SIGNER_C;
        signers[3] = SIGNER_D;
        signers[4] = SIGNER_E;
        address[] memory noPauseTargets = new address[](0);
        governance = new MultisigGovernanceV3(
            signers, 3, TIMELOCK, TIMELOCK, GUARDIAN, TIMELOCK, noPauseTargets, new address[](0), new bytes32[](0)
        );
        rewards = new RewardProgramV3(address(governance));
        consensus = new ThresholdConsensusV3(address(governance), 3);
        disputes = new DisputeRegistryV3(address(governance));
        controller = new BasePilotAccessControllerV3(address(governance), 0.4 ether, 0.2 ether);
        factory = new SafeBondFactoryV3(
            address(governance),
            address(consensus),
            address(disputes),
            address(controller),
            0.01 ether,
            0.02 ether,
            0.2 ether,
            0.02 ether,
            0.2 ether,
            bytes32(uint256(1)),
            bytes32(uint256(2)),
            bytes32(uint256(3)),
            bytes32(uint256(4)),
            bytes32(uint256(5))
        );
    }

    function testBootstrapCannotEnableWritesAuthorizeRolesOrClaimPilotReady() external {
        assertEq(governance.threshold(), 3);
        assertEq(governance.signers(0), SIGNER_A);
        assertEq(governance.signers(4), SIGNER_E);
        assertEq(governance.guardian(), GUARDIAN);
        assertFalse(controller.deployEnabled());
        assertFalse(controller.writeEnabled());
        assertEq(controller.globalCap(), 0);
        assertEq(controller.perPositionCap(), 0);
        assertEq(controller.maxGlobalCap(), 0.4 ether);
        assertEq(controller.maxPerPositionCap(), 0.2 ether);
        assertFalse(controller.isDesignPartner(PARTNER));
        assertFalse(controller.isModule(address(factory)));
        assertFalse(factory.deployAllowed());
        assertEq(address(factory.partnershipFactory()), address(0));
        assertEq(address(factory.accountabilityFactory()), address(0));
        assertEq(consensus.threshold(), 3);
        assertEq(consensus.attesterCount(), 0);
        assertEq(disputes.adjudicatorCount(), 0);

        vm.expectRevert(BasePilotAccessControllerCoreV3.NotGovernance.selector);
        controller.setDeployEnabled(true);
        vm.expectRevert(BasePilotAccessControllerCoreV3.NotGovernance.selector);
        controller.setWriteEnabled(true);
        vm.expectRevert(BasePilotAccessControllerCoreV3.NotGovernance.selector);
        controller.setDesignPartner(PARTNER, true);
        vm.expectRevert(BasePilotAccessControllerCoreV3.NotGovernance.selector);
        controller.setModule(address(factory), true);
        vm.expectRevert(ThresholdConsensusV3.NotOwner.selector);
        consensus.setAttester(PARTNER, true);
        vm.expectRevert(DisputeRegistryV3.NotOwner.selector);
        disputes.setAdjudicator(PARTNER, true);
        vm.expectRevert(SafeBondFactoryV3.NotOwner.selector);
        factory.setDeployAllowed(true);
        vm.expectRevert(SafeBondFactoryV3.NotOwner.selector);
        factory.configureFactories(address(0xB001), address(0xB002));
    }

    function testBootstrapRejectsDirectGovernanceValueAndCannotCreateValuePositions() external {
        vm.deal(address(this), 1 ether);
        (bool accepted,) = address(governance).call{ value: 1 wei }("");
        assertFalse(accepted, "governance must not accept direct native value during bootstrap");
        assertEq(address(governance).balance, 0);

        vm.expectRevert(BasePilotAccessControllerCoreV3.NotModule.selector);
        controller.registerPosition(PARTNER, address(0xA001), 0);
        vm.expectRevert(SafeBondFactoryV3.NotOwner.selector);
        factory.deployPartnership(PARTNER, address(0));
        assertEq(controller.totalAllocated(), 0);
    }
}
