namespace CryptoExchange.Net.Objects
{
    /// <summary>
    /// What to do when a request would exceed the rate limit
    /// </summary>
    public enum RateLimitingBehaviour
    {
        /// <summary>
        /// Fail the request
        /// </summary>
        Fail,
        /// <summary>
        /// Wait till the request can be send
        /// </summary>
        Wait
    }

    /// <summary>
    /// What to do when a request would exceed the rate limit
    /// </summary>
    public enum RateLimitWindowType
    {
        /// <summary>
        /// A sliding window
        /// </summary>
        Sliding,
        /// <summary>
        /// A fixed interval window
        /// </summary>
        Fixed,
        /// <summary>
        /// A fixed interval starting after the first request
        /// </summary>
        FixedAfterFirst,
        /// <summary>
        /// Decaying window
        /// </summary>
        Decay
    }

    /// <summary>
    /// Where the parameters for a HttpMethod should be added in a request
    /// </summary>
    public enum HttpMethodParameterPosition
    {
        /// <summary>
        /// Parameters in body
        /// </summary>
        InBody,
        /// <summary>
        /// Parameters in url
        /// </summary>
        InUri
    }

    /// <summary>
    /// The format of the request body
    /// </summary>
    public enum RequestBodyFormat
    {
        /// <summary>
        /// Form data
        /// </summary>
        FormData,
        /// <summary>
        /// Json
        /// </summary>
        Json
    }

    /// <summary>
    /// Tracker sync status
    /// </summary>
    public enum SyncStatus
    {
        /// <summary>
        /// Not connected
        /// </summary>
        Disconnected,
        /// <summary>
        /// Syncing, data connection is being made
        /// </summary>
        Syncing,
        /// <summary>
        /// The connection is active, but the full data backlog is not yet reached. For example, a tracker set to retain 10 minutes of data only has 8 minutes of data at this moment.
        /// </summary>
        PartiallySynced,
        /// <summary>
        /// Synced
        /// </summary>
        Synced,
        /// <summary>
        /// Disposed
        /// </summary>
        Disposed
    }

    /// <summary>
    /// Status of the order book
    /// </summary>
    public enum OrderBookStatus
    {
        /// <summary>
        /// Not connected
        /// </summary>
        Disconnected,
        /// <summary>
        /// Connecting
        /// </summary>
        Connecting,
        /// <summary>
        /// Reconnecting
        /// </summary>
        Reconnecting,
        /// <summary>
        /// Syncing data
        /// </summary>
        Syncing,
        /// <summary>
        /// Data synced, order book is up to date
        /// </summary>
        Synced,
        /// <summary>
        /// Disposing
        /// </summary>
        Disposing,
        /// <summary>
        /// Disposed
        /// </summary>
        Disposed
    }

    /// <summary>
    /// Order book entry type
    /// </summary>
    public enum OrderBookEntryType
    {
        /// <summary>
        /// Ask
        /// </summary>
        Ask,
        /// <summary>
        /// Bid
        /// </summary>
        Bid
    }

    /// <summary>
    /// Define how array parameters should be send
    /// </summary>
    public enum ArrayParametersSerialization
#pragma warning disable CS1570 // XML comment has badly formed XML
    {
        /// <summary>
        /// Send as key=value1&key=value2
        /// </summary>
        MultipleValues,

        /// <summary>
        /// Send as key[]=value1&key[]=value2
        /// </summary>
        Array,
        /// <summary>
        /// Send as key=[value1, value2]
        /// </summary>
        JsonArray
#pragma warning restore CS1570 // XML comment has badly formed XML
    }

    /// <summary>
    /// How to round
    /// </summary>
    public enum RoundingType
    {
        /// <summary>
        /// Round down (flooring)
        /// </summary>
        Down,
        /// <summary>
        /// Round to closest value
        /// </summary>
        Closest,
        /// <summary>
        /// Round up (ceil)
        /// </summary>
        Up
    }

    /// <summary>
    /// Type of the update
    /// </summary>
    public enum SocketUpdateType
    {
        /// <summary>
        /// A update
        /// </summary>
        Update,
        /// <summary>
        /// A snapshot, generally send at the start of the connection
        /// </summary>
        Snapshot
    }

    /// <summary>
    /// Reconnect policy
    /// </summary>
    public enum ReconnectPolicy
    {
        /// <summary>
        /// Reconnect is disabled
        /// </summary>
        Disabled,
        /// <summary>
        /// Fixed delay of `ReconnectInterval` between retries
        /// </summary>
        FixedDelay,
        /// <summary>
        /// Backoff policy of 2^`reconnectAttempt`, where `reconnectAttempt` has a max value of 5
        /// </summary>
        ExponentialBackoff
    }

    /// <summary>
    /// The data source of the result
    /// </summary>
    public enum ResultDataSource
    {
        /// <summary>
        /// From server
        /// </summary>
        Server,
        /// <summary>
        /// From cache
        /// </summary>
        Cache
    }

    /// <summary>
    /// Type of exchange
    /// </summary>
    public enum ExchangeType
    {
        /// <summary>
        /// Centralized
        /// </summary>
        CEX,
        /// <summary>
        /// Decentralized
        /// </summary>
        DEX
    }

    /// <summary>
    /// Type of platform
    /// </summary>
    public enum PlatformType 
    { 
        /// <summary>
        /// Platform to trade cryptocurrency
        /// </summary>
        CryptoCurrencyExchange,
        /// <summary>
        /// Platform for trading on predictions
        /// </summary>
        PredictionMarket,
        /// <summary>
        /// Other
        /// </summary>
        Other
    }

    /// <summary>
    /// Centralization type
    /// </summary>
    public enum CentralizationType
    {
        /// <summary>
        /// Centralized, a person or company is in full control
        /// </summary>
        Centralized,
        /// <summary>
        /// Decentralized, governance is split over different entities with no single entity in full control
        /// </summary>
        Decentralized
    }

    /// <summary>
    /// Timeout behavior for queries
    /// </summary>
    public enum TimeoutBehavior
    {
        /// <summary>
        /// Fail the request
        /// </summary>
        Fail,
        /// <summary>
        /// Mark the query as successful
        /// </summary>
        Succeed
    }

    /// <summary>
    /// Subscription status
    /// </summary>
    public enum SubscriptionStatus
    {
        /// <summary>
        /// Pending, waiting before (re)subscription can be started
        /// </summary>
        Pending,
        /// <summary>
        /// Currently (re)subscribing, will start producing updates soon if subscription is successful
        /// </summary>
        Subscribing,
        /// <summary>
        /// Subscribed and listening to updates
        /// </summary>
        Subscribed,
        /// <summary>
        /// Subscription is being closed and will stop producing updates
        /// </summary>
        Closing,
        /// <summary>
        /// Subscription is closed and will no long produce updates
        /// </summary>
        Closed
    }

    /// <summary>
    /// Queue full behavior
    /// </summary>
    public enum QueueFullBehavior
    {
        /// <summary>Remove and ignore the newest item in the queue in order to make room for the item being written.</summary>
        DropNewest,
        /// <summary>Remove and ignore the oldest item in the queue in order to make room for the item being written.</summary>
        DropOldest,
        /// <summary>Drop the item being written.</summary>
        DropWrite
    }
}
