package com.shin1ogawa.entity;

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

import javax.jdo.JDOOptimisticVerificationException;
import javax.jdo.PersistenceManager;
import javax.jdo.Transaction;

import org.junit.Before;
import org.junit.Test;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.shin1ogawa.AbstractRelasionShipTest;

public class VersionedNamedKeyTest extends AbstractRelasionShipTest {
	private static final String KIND = VersionedNamedKey.class.getSimpleName();

	@Before
	public void setUp() {
		super.setUp();
		VersionedNamedKey a = new VersionedNamedKey();
		a.setKey(KeyFactory.createKey(KIND, "a"));
		VersionedNamedKey b = new VersionedNamedKey();
		b.setKey(KeyFactory.createKey(KIND, "b"));
		VersionedNamedKey c = new VersionedNamedKey();
		c.setKey(KeyFactory.createKey(KIND, "c"));
		VersionedNamedKey d = new VersionedNamedKey();
		d.setKey(KeyFactory.createKey(KIND, "d"));
		getFactory().getPersistenceManager().makePersistent(a);
		getFactory().getPersistenceManager().makePersistent(b);
		getFactory().getPersistenceManager().makePersistent(c);
		getFactory().getPersistenceManager().makePersistent(d);
	}

	@Test(expected = JDOOptimisticVerificationException.class)
	public void 普通に楽観的排他制御() {
		Key KEY_A = KeyFactory.createKey(KIND, "a");

		PersistenceManager manager1 = getFactory().getPersistenceManager();
		VersionedNamedKey a1 = manager1.getObjectById(VersionedNamedKey.class,
				KEY_A);
		a1.setValue(100);
		PersistenceManager manager2 = getFactory().getPersistenceManager();
		VersionedNamedKey a2 = manager2.getObjectById(VersionedNamedKey.class,
				KEY_A);
		a2.setValue(200);

		Transaction transaction = manager1.currentTransaction();
		transaction.begin();
		manager1.makePersistent(a1);
		transaction.commit();
		manager1.close();
		transaction = manager2.currentTransaction();
		transaction.begin();
		manager2.makePersistent(a2);
		transaction.commit();
	}

	@Test
	// (expected = JDOOptimisticVerificationException.class)
	public void バージョンも何も無い状態で偶然同じ名称でキーを作った場合() {
		Key KEY_E = KeyFactory.createKey(KIND, "e");

		VersionedNamedKey e1 = new VersionedNamedKey();
		e1.setKey(KEY_E);
		e1.setValue(100);
		
		VersionedNamedKey e2 = new VersionedNamedKey();
		e2.setKey(KEY_E);
		e2.setValue(200);

		PersistenceManager manager1 = getFactory().getPersistenceManager();
		Transaction transaction = manager1.currentTransaction();
		transaction.begin();
		manager1.makePersistent(e1);
		transaction.commit();
		manager1.close();
		
		PersistenceManager manager2 = getFactory().getPersistenceManager();
		transaction = manager2.currentTransaction();
		transaction.begin();
		manager2.makePersistent(e2);
		transaction.commit();
		manager2.close();
		
		VersionedNamedKey e = getFactory().getPersistenceManager().getObjectById(VersionedNamedKey.class, KEY_E);
		assertThat(e.getValue(), is(equalTo(200))); // 後勝ち！？
	}
}
