using JSMR.Application.Common.Caching;
using JSMR.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;

namespace JSMR.Infrastructure.Caching;

public abstract class CacheObject<T>(ICache cache) : ICacheObject<T>
{
    protected abstract string Key { get; }
    protected abstract Task<T> FetchAsync(CancellationToken cancellationToken = default);

    protected virtual CacheEntryOptions Options => new() { SlidingExpiration = TimeSpan.FromHours(1) };

    public async virtual Task<T> GetAsync(CancellationToken cancellationToken = default)
    {
        return await cache.GetAsync<T>(Key, cancellationToken) ?? await RefreshAsync(cancellationToken);
    }

    public async virtual Task<T> RefreshAsync(CancellationToken cancellationToken = default)
    {
        T cacheObject = await FetchAsync(cancellationToken);

        await cache.SetAsync(Key, cacheObject, Options, cancellationToken);

        return cacheObject;
    }
}