package com.example.wordbook.common;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import android.test.AndroidTestCase;

/**
 * データ管理クラステストクラス
 */
public class DataManagerTest extends AndroidTestCase {

	/*
	 * (非 Javadoc)
	 * 
	 * @see android.test.AndroidTestCase#setUp()
	 */
	@Override
	protected void setUp() throws Exception {
		super.setUp();
	}

	/*
	 * (非 Javadoc)
	 * 
	 * @see android.test.AndroidTestCase#tearDown()
	 */
	@Override
	protected void tearDown() throws Exception {
		super.tearDown();
	}

	/**
	 * testInit()
	 * 
	 * @throws NoSuchFieldException
	 * @throws IllegalAccessException
	 */
	@SuppressWarnings("unchecked")
	public void testInit() throws NoSuchFieldException, IllegalAccessException {
		// クラスオブジェクト取得
		DataManager dm = new DataManager();
		Class<? extends DataManager> c = dm.getClass();
		// メンバ変数取得
		Field f_base = c.getDeclaredField("mBase");
		Field f_pos = c.getDeclaredField("mPos");
		Field f_data = c.getDeclaredField("mData");
		Field f_temp = c.getDeclaredField("mTemp");
		Field f_result = c.getDeclaredField("mResult");
		Field f_rand = c.getDeclaredField("mRand");
		// アクセス権限追加
		f_base.setAccessible(true);
		f_pos.setAccessible(true);
		f_data.setAccessible(true);
		f_temp.setAccessible(true);
		f_result.setAccessible(true);
		f_rand.setAccessible(true);
		// 初期状態
		int base = 7;
		dm.init(base);

		assertEquals(base, f_base.getInt(dm));
		assertEquals(0, f_pos.getInt(dm));
		assertEquals(0, ((ArrayList<Data>) f_data.get(dm)).size());
		assertEquals(0, ((ArrayList<Data>) f_temp.get(dm)).size());
		assertEquals(-1, f_result.getInt(dm));
		assertEquals(0, ((ArrayList<Data>) f_rand.get(dm)).size());
	}

	/**
	 * testSetNextPos()
	 * 
	 * @throws NoSuchFieldException
	 * @throws IllegalAccessException
	 */
	public void testSetNextPos() throws NoSuchFieldException,
			IllegalAccessException {
		// クラスオブジェクト取得
		DataManager dm = new DataManager();
		Class<? extends DataManager> c = dm.getClass();
		// メンバ変数取得
		Field f_base = c.getDeclaredField("mBase");
		Field f_pos = c.getDeclaredField("mPos");
		Field f_data = c.getDeclaredField("mData");
		Field f_temp = c.getDeclaredField("mTemp");
		Field f_result = c.getDeclaredField("mResult");
		Field f_rand = c.getDeclaredField("mRand");
		// アクセス権限追加
		f_base.setAccessible(true);
		f_pos.setAccessible(true);
		f_data.setAccessible(true);
		f_temp.setAccessible(true);
		f_result.setAccessible(true);
		f_rand.setAccessible(true);
		// 初期状態
		int base = 0;
		dm.init(base);

		// 次のNG位置を設定してtrueを返す
		// データが無くなればfalseを返す
		List<Data> list = new ArrayList<Data>();

		// NG,NG,NG,NG
		int[] stat0 = { Data.STAT_NG, Data.STAT_NG, Data.STAT_NG, Data.STAT_NG };
		for (int i = 0; i < stat0.length; i++) {
			list.add(new Data(i, stat0[i], 0, 0, 0, 0, "Q", "A", "D1", "D2"));
		}
		f_data.set(dm, list);
		f_pos.setInt(dm, 0);
		assertTrue(dm.setNextPos());
		assertEquals(1, dm.getDataPos());
		assertTrue(dm.setNextPos());
		assertEquals(2, dm.getDataPos());
		assertTrue(dm.setNextPos());
		assertEquals(3, dm.getDataPos());
		assertFalse(dm.setNextPos());
		assertEquals(3, dm.getDataPos());
		list.clear();

		// OK,NG,NG,NG
		int[] stat1 = { Data.STAT_OK, Data.STAT_NG, Data.STAT_NG, Data.STAT_NG };
		for (int i = 0; i < stat1.length; i++) {
			list.add(new Data(i, stat1[i], 0, 0, 0, 0, "Q", "A", "D1", "D2"));
		}
		f_data.set(dm, list);
		f_pos.setInt(dm, 0);
		assertTrue(dm.setNextPos());
		assertEquals(1, dm.getDataPos());
		assertTrue(dm.setNextPos());
		assertEquals(2, dm.getDataPos());
		assertTrue(dm.setNextPos());
		assertEquals(3, dm.getDataPos());
		assertFalse(dm.setNextPos());
		assertEquals(3, dm.getDataPos());
		list.clear();

		// OK,OK,NG,NG
		int[] stat2 = { Data.STAT_OK, Data.STAT_OK, Data.STAT_NG, Data.STAT_NG };
		for (int i = 0; i < stat2.length; i++) {
			list.add(new Data(i, stat2[i], 0, 0, 0, 0, "Q", "A", "D1", "D2"));
		}
		f_data.set(dm, list);
		f_pos.setInt(dm, 0);
		assertTrue(dm.setNextPos());
		assertEquals(2, dm.getDataPos());
		assertTrue(dm.setNextPos());
		assertEquals(3, dm.getDataPos());
		assertFalse(dm.setNextPos());
		assertEquals(3, dm.getDataPos());
		list.clear();

		// OK,OK,OK,NG
		int[] stat3 = { Data.STAT_OK, Data.STAT_OK, Data.STAT_OK, Data.STAT_NG };
		for (int i = 0; i < stat3.length; i++) {
			list.add(new Data(i, stat3[i], 0, 0, 0, 0, "Q", "A", "D1", "D2"));
		}
		f_data.set(dm, list);
		f_pos.setInt(dm, 0);
		assertTrue(dm.setNextPos());
		assertEquals(3, dm.getDataPos());
		assertFalse(dm.setNextPos());
		assertEquals(3, dm.getDataPos());
		list.clear();

		// OK,OK,OK,OK
		int[] stat4 = { Data.STAT_OK, Data.STAT_OK, Data.STAT_OK, Data.STAT_OK };
		for (int i = 0; i < stat4.length; i++) {
			list.add(new Data(i, stat4[i], 0, 0, 0, 0, "Q", "A", "D1", "D2"));
		}
		f_data.set(dm, list);
		f_pos.setInt(dm, 0);
		assertFalse(dm.setNextPos());
		assertEquals(3, dm.getDataPos());
		list.clear();
	}

	/**
	 * testSetZeroPos()
	 * 
	 * @throws NoSuchFieldException
	 * @throws IllegalAccessException
	 */
	@SuppressWarnings("unchecked")
	public void testSetZeroPos() throws NoSuchFieldException,
			IllegalAccessException {
		// クラスオブジェクト取得
		DataManager dm = new DataManager();
		Class<? extends DataManager> c = dm.getClass();
		// メンバ変数取得
		Field f_base = c.getDeclaredField("mBase");
		Field f_pos = c.getDeclaredField("mPos");
		Field f_data = c.getDeclaredField("mData");
		Field f_temp = c.getDeclaredField("mTemp");
		Field f_result = c.getDeclaredField("mResult");
		Field f_rand = c.getDeclaredField("mRand");
		// アクセス権限追加
		f_base.setAccessible(true);
		f_pos.setAccessible(true);
		f_data.setAccessible(true);
		f_temp.setAccessible(true);
		f_result.setAccessible(true);
		f_rand.setAccessible(true);
		// 初期状態
		int base = 0;
		dm.init(base);

		// 最初のNG位置を設定する
		// NGが無ければ全てのstatをNGに変更して0を設定する
		List<Data> list = new ArrayList<Data>();

		// NG,NG,NG,NG
		int[] stat0 = { Data.STAT_NG, Data.STAT_NG, Data.STAT_NG, Data.STAT_NG };
		for (int i = 0; i < stat0.length; i++) {
			list.add(new Data(i, stat0[i], 0, 0, 0, 0, "Q", "A", "D1", "D2"));
		}
		f_data.set(dm, list);
		dm.setZeroPos();
		assertEquals(0, dm.getDataPos());
		list.clear();

		// OK,NG,NG,NG
		int[] stat1 = { Data.STAT_OK, Data.STAT_NG, Data.STAT_NG, Data.STAT_NG };
		for (int i = 0; i < stat1.length; i++) {
			list.add(new Data(i, stat1[i], 0, 0, 0, 0, "Q", "A", "D1", "D2"));
		}
		f_data.set(dm, list);
		dm.setZeroPos();
		assertEquals(1, dm.getDataPos());
		list.clear();

		// OK,OK,NG,NG
		int[] stat2 = { Data.STAT_OK, Data.STAT_OK, Data.STAT_NG, Data.STAT_NG };
		for (int i = 0; i < stat2.length; i++) {
			list.add(new Data(i, stat2[i], 0, 0, 0, 0, "Q", "A", "D1", "D2"));
		}
		f_data.set(dm, list);
		dm.setZeroPos();
		assertEquals(2, dm.getDataPos());
		list.clear();

		// OK,OK,OK,NG
		int[] stat3 = { Data.STAT_OK, Data.STAT_OK, Data.STAT_OK, Data.STAT_NG };
		for (int i = 0; i < stat3.length; i++) {
			list.add(new Data(i, stat3[i], 0, 0, 0, 0, "Q", "A", "D1", "D2"));
		}
		f_data.set(dm, list);
		dm.setZeroPos();
		assertEquals(3, dm.getDataPos());
		list.clear();

		// OK,OK,OK,OK
		int[] stat4 = { Data.STAT_OK, Data.STAT_OK, Data.STAT_OK, Data.STAT_OK };
		for (int i = 0; i < stat4.length; i++) {
			list.add(new Data(i, stat4[i], 0, 0, 0, 0, "Q", "A", "D1", "D2"));
		}
		f_data.set(dm, list);
		dm.setZeroPos();
		assertEquals(0, dm.getDataPos());
		for (int i = 0; i < stat4.length; i++) {
			assertEquals(Data.STAT_NG,
					((List<Data>) f_data.get(dm)).get(i).stat);
		}
		list.clear();
	}

	/**
	 * testSetNextPage()
	 * 
	 * @throws NoSuchFieldException
	 * @throws IllegalAccessException
	 */
	public void testSetNextPage() throws NoSuchFieldException,
			IllegalAccessException {
		// クラスオブジェクト取得
		DataManager dm = new DataManager();
		Class<? extends DataManager> c = dm.getClass();
		// メンバ変数取得
		Field f_base = c.getDeclaredField("mBase");
		Field f_pos = c.getDeclaredField("mPos");
		Field f_data = c.getDeclaredField("mData");
		Field f_temp = c.getDeclaredField("mTemp");
		Field f_result = c.getDeclaredField("mResult");
		Field f_rand = c.getDeclaredField("mRand");
		// アクセス権限追加
		f_base.setAccessible(true);
		f_pos.setAccessible(true);
		f_data.setAccessible(true);
		f_temp.setAccessible(true);
		f_result.setAccessible(true);
		f_rand.setAccessible(true);
		// 初期状態
		int base = 0;
		dm.init(base);

		int count1 = 8; // 初期Data項目数
		List<Data> list = new ArrayList<Data>();
		for (int i = 0; i < count1; i++) {
			list.add(new Data(i + 1, 0, 0, 0, 0, 0, "Q", "A", "D1", "D2"));
		}
		f_data.set(dm, list);
		int count2 = 4; // 初期Temp項目数
		List<Data> temp = new ArrayList<Data>();
		for (int i = 0; i < count2; i++) {
			temp.add(new Data(101 + i, 0, 0, 0, 0, 0, "q", "a", "d1", "d2"));
		}
		f_temp.set(dm, temp);

		// DataがTempに更新される

		dm.setNextPage();
		// 位置クリア
		assertEquals(0, dm.getDataPos());
		// Data更新
		assertEquals(count2, dm.getDataList().size());
		for (int i = 0; i < count2; i++) {
			assertEquals(101 + i, dm.getDataList().get(i).num);
		}
		// Tempクリア
		assertEquals(0, dm.getTempList().size());
	}

	/**
	 * testAddTempList()
	 * 
	 * @throws NoSuchFieldException
	 * @throws IllegalAccessException
	 */
	public void testAddTempList() throws NoSuchFieldException,
			IllegalAccessException {
		// クラスオブジェクト取得
		DataManager dm = new DataManager();
		Class<? extends DataManager> c = dm.getClass();
		// メンバ変数取得
		Field f_base = c.getDeclaredField("mBase");
		Field f_pos = c.getDeclaredField("mPos");
		Field f_data = c.getDeclaredField("mData");
		Field f_temp = c.getDeclaredField("mTemp");
		Field f_result = c.getDeclaredField("mResult");
		Field f_rand = c.getDeclaredField("mRand");
		// アクセス権限追加
		f_base.setAccessible(true);
		f_pos.setAccessible(true);
		f_data.setAccessible(true);
		f_temp.setAccessible(true);
		f_result.setAccessible(true);
		f_rand.setAccessible(true);
		// 初期状態
		int base = 0;
		dm.init(base);

		int count1 = 8; // 初期Data項目数
		List<Data> list = new ArrayList<Data>();
		for (int i = 0; i < count1; i++) {
			list.add(new Data(i + 1, 0, 0, 0, 0, 0, "Q", "A", "D1", "D2"));
		}
		f_data.set(dm, list);
		int count2 = 4; // 初期Temp項目数
		List<Data> temp = new ArrayList<Data>();
		for (int i = 0; i < count2; i++) {
			temp.add(new Data(101 + i, 0, 0, 0, 0, 0, "q", "a", "d1", "d2"));
		}
		f_temp.set(dm, temp);

		// Tempに追加される

		dm.addTempList(list);
		// Temp更新
		assertEquals(count2 + count1, dm.getTempList().size());
		for (int i = 0; i < count2; i++) {
			assertEquals(101 + i, dm.getTempList().get(i).num);
		}
		for (int i = 0; i < count1; i++) {
			assertEquals(i + 1, dm.getTempList().get(count2 + i).num);
		}

		// Temp更新
		dm.addTempList(null);
		// 変更無し
		assertEquals(count2 + count1, dm.getTempList().size());
	}

}
