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

import {IERC20} from "@openzeppelin-contracts/token/ERC20/IERC20.sol";
import {ITreasuryExtender} from "./ITreasuryExtender.sol";
import {IGhostAuthority} from "./IGhostAuthority.sol";

interface IAllocator {
    error OnlyExtender(address sender);
    error AllocatorNotActivated();
    error AllocatorNotOffline();
    error Migrating();
    error NotMigrating();

    enum AllocatorStatus {
        OFFLINE,
        ACTIVATED,
        MIGRATING
    }

    struct AllocatorInitData {
        IGhostAuthority authority;
        ITreasuryExtender extender;
        IERC20[] tokens;
    }

    event AllocatorDeployed(address authority, address extender);
    event AllocatorActivated();
    event AllocatorDeactivated(bool panic);
    event LossLimitViolated(uint128 lastLoss, uint128 dloss, uint256 estimatedTotalAllocated);
    event MigrationExecuted(address allocator);
    event EtherReceived(uint256 amount);

    function update(uint256 id) external;
    function deallocate(uint256[] memory amounts) external;
    function prepareMigration() external;
    function migrate() external;
    function activate() external;
    function deactivate(bool panic) external;
    function addId(uint256 id) external;
    function name() external view returns (string memory);
    function ids() external view returns (uint256[] memory);
    function tokenIds(uint256 id) external view returns (uint256);
    function version() external view returns (string memory);
    function status() external view returns (AllocatorStatus);
    function tokens() external view returns (IERC20[] memory);
    function utilityTokens() external view returns (IERC20[] memory);
    function rewardTokens() external view returns (IERC20[] memory);
    function amountAllocated(uint256 id) external view returns (uint256);
}
