package com.example.pc_spring_rest_jersey;

import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.Collections;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

@Component
public class Clipboard {
	private final ConcurrentHashMap<String, String> values = new ConcurrentHashMap<>();
	private final AtomicLong readCount = new AtomicLong();
	private final AtomicLong writeCount = new AtomicLong();
	
	public int getSize() {
		return values.size();
	}
	
	public String get(String key) throws NoSuchElementException {
		Objects.requireNonNull(key);
		readCount.getAndIncrement();
		String value = values.get(key);
		if(value == null) {
			throw new NoSuchElementException("No value at key " + key);
		}
		return value;
	}

	public void set(String key, String value) {
		if(value == null) {
			this.remove(key);
		} else {
			Objects.requireNonNull(key);
			writeCount.getAndIncrement();
			values.put(key, value);
		}
	}
	
	public String remove(String key) throws NoSuchElementException {
		Objects.requireNonNull(key);
		String value = values.remove(key);
		if(value == null) {
			throw new NoSuchElementException("No value to remove at key " + key);
		}
		return value;
	}
	
	public Collection<String> getAllKeys() {
		return Collections.unmodifiableSet(values.keySet());
	}
	
	public long getReadCount() {
		return readCount.get();
	}

	public long getWriteCount() {
		return writeCount.get();
	}
	
	@Override
	public String toString() {
		return "Clipboard with " + getSize() + " entries";
	}

}
