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

import {CheckpointLeaf} from "../libraries/CheckpointLeaf.sol";

/**
 * @title CheckpointStorage
 * @notice EIP-7201 namespaced storage for upgradeable checkpoint hub.
 */
library CheckpointStorage {
    /// @custom:storage-location erc7201:dbis.storage.Chain138MainnetCheckpoint
    struct CheckpointStorageStruct {
        uint64 latestBatchId;
        uint256 latestCheckpointBlock;
        bytes32 latestPaymentsRoot;
        uint64 chainId;
        uint16 batchSize;
        uint32 maxBatchWaitSeconds;
        uint256 minPaymentValueWei;
        bool requireValidatorSigs;
        bool allowCalldataOnlySubmit;
        bool allowCCIPIngress;
        bool enforcePreviousBatchId;
        bool paused;
        uint64 expectedSourceChainSelector;
        address batchEmitterOnSource;
        address ccipRouter;
        address legacyMirrorV1;
        address legacyTetherV1;
        address submitterAttestationSigner;
        mapping(uint64 => CheckpointHeader) checkpoints;
        mapping(bytes32 => bool) processedProofHashes;
        mapping(bytes32 => uint64) txHashToBatchId;
        mapping(uint64 => bool) processedBatchIds;
        mapping(bytes32 => ExtensionConfig) extensions;
        bytes32[] extensionList;
        uint256[37] __gap;
    }

    struct CheckpointHeader {
        uint64 batchId;
        uint64 previousBatchId;
        uint64 chainId;
        uint256 checkpointBlock;
        uint256 startBlock;
        uint256 endBlock;
        bytes32 blockHash;
        bytes32 stateRoot;
        bytes32 paymentsRoot;
        bytes32 receiptsRoot;
        uint16 txCount;
        uint32 flags;
        uint64 submittedAt;
        address submitter;
        bytes32 contentURI;
    }

    struct ExtensionConfig {
        address module;
        uint32 hooks;
        bool active;
    }

    // keccak256(abi.encode(uint256(keccak256("dbis.storage.Chain138MainnetCheckpoint")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant CHECKPOINT_STORAGE_LOCATION =
        0x94db105fe8bb9354ca3efbce04a4b0527821f7a844cf050ca0ad49fe0d3aad00;

    function get() internal pure returns (CheckpointStorageStruct storage $) {
        assembly {
            $.slot := CHECKPOINT_STORAGE_LOCATION
        }
    }
}
