using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
namespace Discord.Net
{
///
/// Represents a ratelimit bucket.
///
public class BucketId : IEquatable
{
///
/// Gets the http method used to make the request if available.
///
public string HttpMethod { get; }
///
/// Gets the endpoint that is going to be requested if available.
///
public string Endpoint { get; }
///
/// Gets the major parameters of the route.
///
public IOrderedEnumerable> MajorParameters { get; }
///
/// Gets the hash of this bucket.
///
///
/// The hash is provided by Discord to group ratelimits.
///
public string BucketHash { get; }
///
/// Gets if this bucket is a hash type.
///
public bool IsHashBucket { get => BucketHash != null; }
private BucketId(string httpMethod, string endpoint, IEnumerable> majorParameters, string bucketHash)
{
HttpMethod = httpMethod;
Endpoint = endpoint;
MajorParameters = majorParameters.OrderBy(x => x.Key);
BucketHash = bucketHash;
}
///
/// Creates a new based on the
/// and .
///
/// Http method used to make the request.
/// Endpoint that is going to receive requests.
/// Major parameters of the route of this endpoint.
///
/// A based on the
/// and the with the provided data.
///
public static BucketId Create(string httpMethod, string endpoint, Dictionary majorParams)
{
Preconditions.NotNullOrWhitespace(endpoint, nameof(endpoint));
majorParams = majorParams ?? new Dictionary();
return new BucketId(httpMethod, endpoint, majorParams, null);
}
///
/// Creates a new based on a
/// and a previous .
///
/// Bucket hash provided by Discord.
/// that is going to be upgraded to a hash type.
///
/// A based on the
/// and .
///
public static BucketId Create(string hash, BucketId oldBucket)
{
Preconditions.NotNullOrWhitespace(hash, nameof(hash));
Preconditions.NotNull(oldBucket, nameof(oldBucket));
return new BucketId(null, null, oldBucket.MajorParameters, hash);
}
///
/// Gets the string that will define this bucket as a hash based one.
///
///
/// A that defines this bucket as a hash based one.
///
public string GetBucketHash()
=> IsHashBucket ? $"{BucketHash}:{string.Join("/", MajorParameters.Select(x => x.Value))}" : null;
///
/// Gets the string that will define this bucket as an endpoint based one.
///
///
/// A that defines this bucket as an endpoint based one.
///
public string GetUniqueEndpoint()
=> HttpMethod != null ? $"{HttpMethod} {Endpoint}" : Endpoint;
public override bool Equals(object obj)
=> Equals(obj as BucketId);
public override int GetHashCode()
=> IsHashBucket ? (BucketHash, string.Join("/", MajorParameters.Select(x => x.Value))).GetHashCode() : (HttpMethod, Endpoint).GetHashCode();
public override string ToString()
=> GetBucketHash() ?? GetUniqueEndpoint();
public bool Equals(BucketId other)
{
if (other is null)
return false;
if (ReferenceEquals(this, other))
return true;
if (GetType() != other.GetType())
return false;
return ToString() == other.ToString();
}
}
}