using System;
using System.Threading;
namespace Renci.SshNet.Common
{
    /// 
    /// Light implementation of SemaphoreSlim.
    /// 
    public class SemaphoreLight
    {
        private readonly object _lock = new object();
        private int _currentCount;
        /// 
        /// Initializes a new instance of the  class, specifying 
        /// the initial number of requests that can be granted concurrently.
        /// 
        /// The initial number of requests for the semaphore that can be granted concurrently.
        ///  is a negative number.
        public SemaphoreLight(int initialCount)
        {
            if (initialCount < 0 )
                throw new ArgumentOutOfRangeException("initialCount", "The value cannot be negative.");
            this._currentCount = initialCount;
        }
        /// 
        /// Gets the current count of the .
        /// 
        public int CurrentCount { get { return this._currentCount; } }
        /// 
        /// Exits the  once.
        /// 
        /// The previous count of the .
        public int Release()
        {
            return this.Release(1);
        }
        /// 
        /// Exits the  a specified number of times.
        /// 
        /// The number of times to exit the semaphore.
        /// The previous count of the .
        public int Release(int releaseCount)
        {
            var oldCount = this._currentCount;
            lock (this._lock)
            {
                this._currentCount += releaseCount;
                Monitor.Pulse(this._lock);
            }
            return oldCount;
        }
        /// 
        /// Blocks the current thread until it can enter the .
        /// 
        public void Wait()
        {
            lock (this._lock)
            {
                while (this._currentCount < 1)
                {
                    Monitor.Wait(this._lock);
                }
                this._currentCount--;
                Monitor.Pulse(this._lock);
            }
        }
    }
}