package ca.recrown.islandsurvivalcraft.caching;

import java.util.concurrent.locks.ReentrantLock;

class UsageStack<K, V> {
    private volatile CacheValue<K, V> first, last;
    private final ReentrantLock lock = new ReentrantLock();

    private void addToTop(CacheValue<K, V> value) {
        if (first != null) {
            first.front = value;
            value.back = first;
        } else {
            last = value;
        }
        value.front = null;
        first = value;
    }

    private void removeValue(CacheValue<K, V> value) {
        if (value.front != null) {
            value.front.back = value.back;
        } else {
            first = value.back;
        }
        if (value.back != null) {
            value.back.front = value.front;
        } else {
            last = value.front;
        }
        value.front = null;
        value.back = null;
    }

    public void moveToTop(CacheValue<K, V> value) {
        lock.lock();
        try {
            removeValue(value);
            addToTop(value);
        } finally {
            lock.unlock();
        }
    }

    public boolean tryMoveToTop(CacheValue<K, V> value) {
        boolean success = false;
        success = lock.tryLock();
        if (success) {
            try {
                removeValue(value);
                addToTop(value);
            } finally {
                lock.unlock();
            }
        }
        return success;
    }

    public void add(CacheValue<K, V> value) {
        lock.lock();
        try {
            addToTop(value);
        } finally {
            lock.unlock();
        }
    }

    public CacheValue<K, V> pop() {
        CacheValue<K, V> cacheValue;
        lock.lock();
        try {
            cacheValue = last;
            removeValue(last);
        } finally {
            lock.unlock();
        }
        return cacheValue;
    }

    public void clear() {
        lock.lock();
        try {
            first = null;
            last = null;
        } finally {
            lock.unlock();
        }
    }
}