using System;
using Enyim.Caching;
using Enyim.Caching.Memcached;
using Microsoft.Extensions.Logging;

namespace Expedience.Infrastructure.Concurrency
{
    public interface IDistributedLock
    {
        bool AcquireLock(string lockKey, TimeSpan timeout, TimeSpan lockExpiration);
        void ReleaseLock(string lockKey);
    }

    public class DistributedLock : IDistributedLock
    {
        private readonly IMemcachedClient _memcachedClient;

        public DistributedLock(ILogger<DistributedLock> logger, IMemcachedClient memcachedClient)
        {
            _memcachedClient = memcachedClient;
         }

        public bool AcquireLock(string lockKey, TimeSpan timeout, TimeSpan lockExpiration)
        {
            var startTime = DateTime.UtcNow;
            while (true)
            {
                if (_memcachedClient.Store(StoreMode.Add, lockKey, true, lockExpiration))
                {
                    return true; // Lock acquired
                }

                if (DateTime.UtcNow - startTime > timeout)
                {
                    return false; // Timeout
                }

                Thread.Sleep(100); // Wait and try again
            }
        }

        public void ReleaseLock(string lockKey)
        {
            _memcachedClient.Remove(lockKey);
        }
    }
}
