interface IOperationStore {
    // Events
    event OperationAllocated(
        address indexed controller,
        address indexed operation
    );
    event OperationInitialized(
        address indexed controller,
        address indexed operation,
        bool autoFinish
    );
    event OperationFinished(
        address indexed controller,
        address indexed operation
    );
    event OperationStopped(
        address indexed controller,
        address indexed operation
    );
    event OperationRecovered(
        address indexed controller,
        address indexed operation
    );
    event OperationDeallocated(
        address indexed controller,
        address indexed operation
    );
    event OperationFlushed(
        address indexed controller,
        address indexed operation,
        Queue from,
        Queue to
    );

    // Data Structure
    enum Status {
        IDLE,
        RUNNING_AUTO,
        RUNNING_MANUAL,
        FINISHED,
        STOPPED,
        RECOVERED,
        DEALLOCATED
    }

    enum Queue {IDLE, RUNNING, STOPPED, NULL}

    // getter
    function getAvailableOperation() external view returns (address);

    function getQueuedOperationAt(Queue _queue, uint256 _index)
        external
        view
        returns (address);

    function getQueueSizeOf(Queue _queue) external view returns (uint256);

    function getStatusOf(address _opt) external view returns (Status);

    // logics
    function allocate(address _opt) external;

    function init(bool _autoFinish) external returns (address);

    function finish(address _opt) external;

    function halt(address _opt) external;

    function recover(address _opt) external;

    function deallocate(address _opt) external;

    // queue
    function flush(Queue queue, uint256 _amount) external;

    function flushAll(uint256 _amount) external; // running, failed
}
function allocate(address _opt) external;

// logics