use thiserror::Error;

#[derive(Error, Debug)]
pub enum ErrorCodes {
    #[error("User class not found")]
    UserClassNotFound,

    #[error("User already paused")]
    UserAlreadyPaused,

    #[error("User already unpaused")]
    UserAlreadyUnpaused,

    #[error("Only liquidity authority")]
    OnlyLiquidityAuthority,

    #[error("Only auth")]
    OnlyAuth,

    #[error("Only guardians")]
    OnlyGuardians,

    #[error("Invalid params")]
    InvalidParams,

    #[error("Invalid config order")]
    InvalidConfigOrder,

    #[error("Status already set")]
    StatusAlreadySet,

    #[error("Limits cannot be zero")]
    LimitsCannotBeZero,

    #[error("Max auth count reached")]
    MaxAuthCountReached,

    #[error("Max user classes reached")]
    MaxUserClassesReached,

    /***********************************|
    |          User Module              |
    |__________________________________*/
    #[error("Insufficient balance")]
    InsufficientBalance,

    #[error("User supply position required")]
    UserSupplyPositionRequired,

    #[error("User borrow position required")]
    UserBorrowPositionRequired,

    #[error("Claim account required")]
    ClaimAccountRequired,

    #[error("Withdraw to account required")]
    WithdrawToAccountRequired,

    #[error("Borrow to account required")]
    BorrowToAccountRequired,

    #[error("Invalid claim amount")]
    InvalidClaimAmount,

    #[error("No amount to claim")]
    NoAmountToClaim,

    #[error("Amount not zero")]
    AmountNotZero,

    #[error("Value overflow")]
    ValueOverflow,

    #[error("Invalid transfer type")]
    InvalidTransferType,

    #[error("Mint mismatch")]
    MintMismatch,

    #[error("User not defined")]
    UserNotDefined,

    #[error("Invalid user claim")]
    InvalidUserClaim,

    /// @notice thrown when user operations are paused for an interacted token
    #[error("User paused")]
    UserPaused,

    /// @notice thrown when user's try to withdraw below withdrawal limit
    #[error("Withdrawal limit reached")]
    WithdrawalLimitReached,

    /// @notice thrown when user's try to borrow above borrow limit
    #[error("Borrow limit reached")]
    BorrowLimitReached,

    /// @notice thrown when user sent supply/withdraw and borrow/payback both are nearly MIN_OPERATE_AMOUNT
    #[error("Operate amounts nearly zero")]
    OperateAmountsNearlyZero,

    /// @notice thrown when user sent supply/withdraw and borrow/payback both are nearly MIN_OPERATE_AMOUNT
    #[error("Operate amount too big")]
    OperateAmountTooBig,

    /// @notice thrown when user sent supply/withdraw and borrow/payback both are nearly MIN_OPERATE_AMOUNT
    #[error("Operate amounts insufficient")]
    OperateAmountsInsufficient,

    /// @notice thrown when user did send excess or insufficient amount (beyond rounding issues)
    #[error("Transfer amount out of bounds")]
    TransferAmountOutOfBounds,

    /// @notice thrown when there is supply / payback in Liquidity, but last instruction is not transfer
    #[error("Forbidden operate call")]
    ForbiddenOperateCall,

    /// @notice thrown when user's try to borrow above max utilization
    #[error("Max utilization reached")]
    MaxUtilizationReached,

    /// @notice all ValueOverflow errors below are thrown if a certain input param or calc result overflows the allowed
    #[error("Value overflow total supply")]
    ValueOverflowTotalSupply,
    #[error("Value overflow total borrow")]
    ValueOverflowTotalBorrow,

    #[error("Deposit expected")]
    DepositExpected,

    /***********************************|
    |         LiquidityHelpers          |
    |__________________________________*/
    // LiquidityCalcs errors
    #[error("Exchange price zero")]
    ExchangePriceZero,

    #[error("Unsupported rate version")]
    UnsupportedRateVersion,

    #[error("Borrow rate negative")]
    BorrowRateNegative,

    // Protocol lockdown
    #[error("Protocol lockdown")]
    ProtocolLockdown,
}
