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

interface ITreasuryExtender {
    error AllocatorNotActivated();
    error AllocatorNotOffline();
    error AllocatorOffline();
    error OnlyAllocator(uint256 id, address sender);
    error AllocatorMaxAllocation(uint256 newAllocated, uint256 oldAllocated);

    event AllocatedWithdrawal(uint256 id, uint256 amount, uint256 value);

    struct AllocatorPerformance {
        uint128 gain;
        uint128 loss;
    }

    struct AllocatorLimits {
        uint128 allocated;
        uint128 loss;
    }

    struct AllocatorHoldings {
        uint256 allocated;
    }

    struct AllocatorData {
        AllocatorHoldings holdings;
        AllocatorLimits limits;
        AllocatorPerformance performance;
    }

    event NewDepositRegistered(address allocator, address token, uint256 id);
    event AllocatorFunded(uint256 id, uint256 amount, uint256 value);
    event AllocatorWithdrawal(uint256 id, uint256 amount, uint256 value);
    event AllocatorRewardsWithdrawal(address allocator, uint256 amount, uint256 value);
    event AllocatorReportedGain(uint256 id, uint128 gain);
    event AllocatorReportedLoss(uint256 id, uint128 loss);
    event AllocatorReportedMigration(uint256 id);
    event AllocatorLimitsChanged(uint256 id, uint128 allocationLimit, uint128 lossLimit);

    function registerDeposit(address newAllocator) external;
    function setAllocatorLimits(uint256 id, AllocatorLimits memory limits) external;

    function report(
        uint256 id,
        uint128 gain,
        uint128 loss
    ) external;

    function requestFundsFromTreasury(uint256 id, uint256 amount) external;
    function returnFundsToTreasury(uint256 id, uint256 amount) external;

    function returnRewardsToTreasury(
        uint256 id,
        address token,
        uint256 amount
    ) external;

    function returnRewardsToTreasury(
        address allocator,
        address token,
        uint256 amount
    ) external;

    function getTotalAllocatorCount() external view returns (uint256);
    function getAllocatorById(uint256 id) external view returns (address);
    function getAllocatorAllocated(uint256 id) external view returns (uint256);
    function getAllocatorLimits(uint256 id) external view returns (AllocatorLimits memory);
    function getAllocatorPerformance(uint256 id) external view returns (AllocatorPerformance memory);
}
