﻿using System.Threading;

namespace Lucene.Net.Support.Threading
{
    /*
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */

    internal class ReentrantLock
    {
        // .NET Port: lock object used to emulate ReentrantLock
        private readonly object _lock = new object();

        // .NET Port: Estimated monitor queue length
        private int _queueLength = 0;

        // .NET Port: mimic ReentrantLock -- Monitor is re-entrant
        public void Lock()
        {
            // note about queue length: in java's ReentrantLock, getQueueLength() returns the number
            // of threads waiting on entering the lock. So here, we're incrementing the count before trying to enter,
            // meaning that until enter has completed the thread is waiting so the queue is incremented. Once
            // we enter the lock, then we immediately decrement it because that thread is no longer in the queue.
            // Due to race conditions, the queue length is an estimate only.
            Interlocked.Increment(ref _queueLength);
            Monitor.Enter(_lock);
            Interlocked.Decrement(ref _queueLength);
        }

        // .NET Port: mimic ReentrantLock -- Monitor is re-entrant
        public void Unlock()
        {
            Monitor.Exit(_lock);
        }

        public bool TryLock()
        {
            Interlocked.Increment(ref _queueLength);
            bool success = Monitor.TryEnter(_lock);
            Interlocked.Decrement(ref _queueLength);

            return success;
        }

        public int QueueLength
        {
            get
            {
                // hold onto the estimate for the length of this method
                int estimate = _queueLength;

                // should never be < 0, but just in case, as a negative number doesn't make sense.
                return estimate <= 0 ? 0 : estimate;
            }
        }

        public bool HasQueuedThreads => _queueLength > 0;

        public bool IsHeldByCurrentThread => Monitor.IsEntered(_lock);
    }
}