package be.jeffcheasey88.peeratcode.framework;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class Locker<V>{
	
	private Map<Key, BlockingQueue<V>> map;
	
	public Locker(){
		this.map = new HashMap<>();
	}
	
	public void init(Key key){
		this.map.put(key, new LinkedBlockingQueue<>());
	}
	
	public void remove(Key key){
		this.map.remove(key);
	}
	
	private BlockingQueue<V> get(Key key){
		return this.map.get(key);
	}
	
	public void setValue(V value){
		for(Entry<Key, BlockingQueue<V>> entry : this.map.entrySet()){
			entry.getValue().add(value);
			this.unlock(entry.getKey());
		}
	}
	
	public V getValue(Key key){
		BlockingQueue<V> queue = get(key);
		if(queue.isEmpty()) return null;
		return queue.poll();
	}

	public void lock(Key key) throws InterruptedException{
		BlockingQueue<V> queue = get(key);
		if(queue.isEmpty()){
			synchronized(queue){
				queue.wait();
			}
		}
	}
	
	public void unlock(Key key){
		BlockingQueue<V> queue = get(key);
		synchronized(queue){
			queue.notify();
		}
	}
	
	public static class Key{ public Key(){} }
}
