using Microsoft.Extensions.Caching.Memory;

namespace BankSampahApp.Services;

/// <summary>
/// Interface untuk cache service yang mengelola caching operations
/// </summary>
public interface ICacheService
{
    /// <summary>
    /// Gets cached value or sets it using the provider function
    /// </summary>
    /// <typeparam name="T">Type of cached data</typeparam>
    /// <param name="key">Cache key</param>
    /// <param name="provider">Function to provide data if not in cache</param>
    /// <param name="expiration">Cache expiration time</param>
    /// <param name="priority">Cache priority</param>
    /// <returns>Cached or fresh data</returns>
    Task<T> GetOrSetAsync<T>(string key, Func<Task<T>> provider, TimeSpan expiration, CacheItemPriority priority = CacheItemPriority.Normal);

    /// <summary>
    /// Gets cached value or sets it using sliding expiration
    /// </summary>
    /// <typeparam name="T">Type of cached data</typeparam>
    /// <param name="key">Cache key</param>
    /// <param name="provider">Function to provide data if not in cache</param>
    /// <param name="slidingExpiration">Sliding expiration time</param>
    /// <param name="absoluteExpiration">Absolute expiration time</param>
    /// <param name="priority">Cache priority</param>
    /// <returns>Cached or fresh data</returns>
    Task<T> GetOrSetWithSlidingAsync<T>(string key, Func<Task<T>> provider, TimeSpan slidingExpiration, TimeSpan absoluteExpiration, CacheItemPriority priority = CacheItemPriority.Normal);

    /// <summary>
    /// Gets value from cache
    /// </summary>
    /// <typeparam name="T">Type of cached data</typeparam>
    /// <param name="key">Cache key</param>
    /// <returns>Cached value or default</returns>
    T? Get<T>(string key);

    /// <summary>
    /// Sets value in cache
    /// </summary>
    /// <typeparam name="T">Type of data to cache</typeparam>
    /// <param name="key">Cache key</param>
    /// <param name="value">Value to cache</param>
    /// <param name="expiration">Cache expiration time</param>
    /// <param name="priority">Cache priority</param>
    void Set<T>(string key, T value, TimeSpan expiration, CacheItemPriority priority = CacheItemPriority.Normal);

    /// <summary>
    /// Removes value from cache
    /// </summary>
    /// <param name="key">Cache key</param>
    void Remove(string key);

    /// <summary>
    /// Removes multiple cache entries by pattern
    /// </summary>
    /// <param name="pattern">Pattern to match cache keys</param>
    void RemoveByPattern(string pattern);

    /// <summary>
    /// Checks if key exists in cache
    /// </summary>
    /// <param name="key">Cache key</param>
    /// <returns>True if key exists</returns>
    bool Exists(string key);
}