package com.wolfninja.keystore.memcached;

import java.util.concurrent.ExecutionException;

import net.spy.memcached.CASResponse;
import net.spy.memcached.CASValue;
import net.spy.memcached.MemcachedClient;

import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.wolfninja.keystore.api.KeyValue;
import com.wolfninja.keystore.api.Keyspace;

public class MemcachedKeyspace implements Keyspace {

	private String keyspaceName;
	private MemcachedClient memcachedClient;

	public MemcachedKeyspace(final String keyspaceName, final MemcachedClient memcachedClient) {
		Preconditions.checkNotNull(keyspaceName, "KeyspaceName must not be null");
		Preconditions.checkNotNull(memcachedClient, "MemcachedClient must not be null");

		this.keyspaceName = keyspaceName;
		this.memcachedClient = memcachedClient;
	}

	private String key(final String key) {
		return keyspaceName + ":" + key;
	}

	@Override
	public boolean add(final String key, final String value) {
		Preconditions.checkNotNull(key, "Key should be provided");
		Preconditions.checkNotNull(value, "Value should be provided");

		try {
			return memcachedClient.add(key(key), 0, value).get();
		} catch (InterruptedException | ExecutionException e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public boolean checkAndSet(final String key, final String value, long version) {
		Preconditions.checkNotNull(key, "Key should be provided");
		Preconditions.checkNotNull(value, "Value should be provided");
		final CASResponse response = memcachedClient.cas(key(key), version, value);
		return response.equals(CASResponse.OK);
	}

	@Override
	public boolean delete(final String key) {
		Preconditions.checkNotNull(key, "Key should be provided");
		try {
			return memcachedClient.delete(key(key)).get();
		} catch (InterruptedException | ExecutionException e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public Optional<KeyValue> get(final String key) {
		Preconditions.checkNotNull(key, "Key should be provided");

		String builtKey = key(key);
		final CASValue<Object> value = memcachedClient.gets(builtKey);
		final KeyValue keyValue = (value == null) ? null : KeyValue.create(key, value.getValue().toString(),
				value.getCas());
		return Optional.fromNullable(keyValue);
	}

	@Override
	public boolean exists(final String key) {
		Preconditions.checkNotNull(key, "Key should be provided");
		return memcachedClient.get(key(key)) != null;
	}

	@Override
	public boolean replace(final String key, final String value) {
		Preconditions.checkNotNull(key, "Key should be provided");
		Preconditions.checkNotNull(value, "Value should be provided");

		try {
			final CASValue<Object> existing = memcachedClient.gets(key(key));
			return memcachedClient.replace(key(key), 0, value).get() && !value.equals(existing.getValue());
		} catch (InterruptedException | ExecutionException e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public boolean set(final String key, final String value) {
		Preconditions.checkNotNull(key, "Key should be provided");
		Preconditions.checkNotNull(value, "Value should be provided");

		try {
			return memcachedClient.set(key(key), 0, value).get();
		} catch (InterruptedException | ExecutionException e) {
			throw new RuntimeException(e);
		}
	}

}

@@ -1889,32 +1889,260 @@
 ion(e);%0A%09%09%7D%0A%09%7D%0A%0A
+%09@Override%0A%09public Optional%3CString%3E get(final String key) %7B%0A%09%09Preconditions.checkNotNull(key, %22Key should be provided%22);%0A%0A%09%09final String value = (String) memcachedClient.get(key(key));%0A%09%09return Optional.fromNullable(value);%0A%09%7D%0A%0A
 %09@Override%0A%09publ
@@ -2162,24 +2162,25 @@
 eyValue%3E get
+s
 (final Strin
@@ -2252,16 +2252,22 @@
 d%22);%0A%0A%09%09
+final 
 String b

Implement simple get from API