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

import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";

/**
 * @title OMNLCircuitBreaker
 * @notice Global / per-line pause; optional block on stale attestation for M1 mint path.
 */
contract OMNLCircuitBreaker is AccessControl {
    bytes32 public constant GUARDIAN_ROLE = keccak256("GUARDIAN_ROLE");
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");

    bool public globalPaused;
    mapping(bytes32 lineId => bool) public linePaused;
    /// @notice If true, M1 mint must revert when attestation is past validUntil (checked in ComplianceCore).
    bool public enforceStaleBlockM1;
    /// @notice If true, M0 mint must revert when attestation is stale.
    bool public enforceStaleBlockM0;

    event GlobalPauseSet(bool paused, address indexed by);
    event LinePauseSet(bytes32 indexed lineId, bool paused, address indexed by);
    event StaleEnforcementSet(bool blockM0, bool blockM1);

    constructor(address admin) {
        require(admin != address(0), "OMNLCircuitBreaker: zero admin");
        _grantRole(DEFAULT_ADMIN_ROLE, admin);
        _grantRole(GUARDIAN_ROLE, admin);
        _grantRole(PAUSER_ROLE, admin);
    }

    function setGlobalPaused(bool paused) external onlyRole(GUARDIAN_ROLE) {
        globalPaused = paused;
        emit GlobalPauseSet(paused, msg.sender);
    }

    function setLinePaused(bytes32 lineId, bool paused) external onlyRole(PAUSER_ROLE) {
        linePaused[lineId] = paused;
        emit LinePauseSet(lineId, paused, msg.sender);
    }

    function setStaleEnforcement(bool blockM0, bool blockM1) external onlyRole(DEFAULT_ADMIN_ROLE) {
        enforceStaleBlockM0 = blockM0;
        enforceStaleBlockM1 = blockM1;
        emit StaleEnforcementSet(blockM0, blockM1);
    }

    function isLineOperational(bytes32 lineId) external view returns (bool) {
        if (globalPaused) return false;
        if (linePaused[lineId]) return false;
        return true;
    }
}
