package com.shin1ogawa;

import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;

import org.apache.commons.lang.StringUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;

import com.google.appengine.api.datastore.dev.LocalDatastoreService;
import com.google.appengine.tools.development.ApiProxyLocalImpl;
import com.google.apphosting.api.ApiProxy;

/**
 * Relationshipのテスト用抽象クラス。
 * <p>
 * testの実行ごとにDatastroreを空にする。<br />
 * また、JavaのLogFormatterを少しカスタマイズしている。
 * </p>
 * 
 * @author shin1ogawa
 */
public class AbstractRelasionShipTest {

	@SuppressWarnings("unused")
	private static final Logger logger = Logger
			.getLogger(AbstractRelasionShipTest.class.getName());

	public static PersistenceManagerFactory factory;

	/**
	 * {@link PersistenceManager}
	 */
	private static PersistenceManager pm;

	static final String LINE_SEPARATOR = System.getProperty("line.separator");

	@BeforeClass
	public static void setUpBeforeClass() {
		if (factory == null) {
			factory = JDOHelper
					.getPersistenceManagerFactory("transactions-optional");
		}
		if (pm == null) {
			pm = factory.getPersistenceManager();
		}
		for (Handler handler : Logger.getAnonymousLogger().getParent()
				.getHandlers()) {
			handler.setFormatter(new Formatter() {
				DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss.SSS");

				@Override
				public String format(LogRecord record) {
					StringBuffer buffer = new StringBuffer();
					String loggerName = record.getLoggerName();
					if (StringUtils.isEmpty(loggerName)) {
						loggerName = "Anonymous logger";
					}
					buffer.append(record.getLevel().getLocalizedName()).append(
							" ").append(
							dateFormat.format(new Date(record.getMillis())))
							.append(" : ").append(loggerName).append(" : ")
							.append(record.getMessage()).append(LINE_SEPARATOR);
					return buffer.toString();
				}
			});
		}
	}

	@Before
	public void setUp() {
		ApiProxy.setEnvironmentForCurrentThread(new TestEnvironment());
		ApiProxy.setDelegate(new ApiProxyLocalImpl(new File(
				"target/relationshipTest")) {
		});
		ApiProxyLocalImpl proxy = (ApiProxyLocalImpl) ApiProxy.getDelegate();
		proxy.setProperty(LocalDatastoreService.NO_STORAGE_PROPERTY,
				Boolean.TRUE.toString());
	}

	@After
	public void tearDown() {
		ApiProxyLocalImpl proxy = (ApiProxyLocalImpl) ApiProxy.getDelegate();
		LocalDatastoreService datastoreService = (LocalDatastoreService) proxy
				.getService("datastore_v3");
		datastoreService.clearProfiles();
		ApiProxy.setDelegate(null);
		ApiProxy.setEnvironmentForCurrentThread(null);
	}

	/**
	 * @param pm
	 *            the pm to set
	 */
	protected static void setPersistenceManager(PersistenceManager pm) {
		AbstractRelasionShipTest.pm = pm;
	}

	/**
	 * @return the pm
	 */
	protected static PersistenceManager getPersistenceManager() {
		return pm;
	}

	public static PersistenceManagerFactory getFactory() {
		return factory;
	}

}
