package eu.ydp.empiria.player.client.controller;

import java.util.List;

import com.google.common.collect.Lists;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.junit.client.GWTTestCase;

import eu.ydp.empiria.player.client.module.HasChildren;
import eu.ydp.empiria.player.client.module.IModule;
import eu.ydp.empiria.player.client.module.IStateful;
import eu.ydp.empiria.player.client.module.IUniqueModule;

public class ModulesStateLoaderGWTTestCase extends GWTTestCase {

	private ModulesStateLoader loader;

	final String FIRST_IDENTIFIER = "EDIT_RESPONSE_1";
	final String SECOND_IDENTIFIER = "EDIT_RESPONSE_2";

	final String FIRST_STATE = "[\"1\"]";
	final String SECOND_STATE = "[\"2\"]";

	private ModuleMock firstModule;

	private ModuleMock secondModule;

	@Override
	public String getModuleName() {
		return "eu.ydp.empiria.player.Player";
	}

	@Override
	protected void gwtSetUp() throws Exception {
		loader = new ModulesStateLoader();

		firstModule = new ModuleMock(FIRST_IDENTIFIER);
		secondModule = new ModuleMock(SECOND_IDENTIFIER);
	}

	public void testDoesntSetStateOnModulesBecauseIsNull() { // given //
		// given
		JSONArray state = null;

		List<IModule> modules = Lists.newArrayList((IModule) firstModule, (IModule) secondModule);

		// when
		loader.setState(state, modules);

		// then
		assertNull(firstModule.getState());
		assertNull(secondModule.getState());
	}

	public void testDoesntSetStateOnModulesBecauseIsEmpty() { // given //
		// given
		String stateString = "{}";

		JSONObject stateObject = getStateObjectByString(stateString);
		JSONArray state = getJSONArrayWithObject(stateObject);

		List<IModule> modules = Lists.newArrayList((IModule) firstModule, (IModule) secondModule);

		// when
		loader.setState(state, modules);

		// then
		assertNull(firstModule.getState());
		assertNull(secondModule.getState());
	}

	public void testSetStateOnFirstModuleOnly() { // given //
		// given
		// @formatter:off
				String stateString = "{\"" +
						FIRST_IDENTIFIER + "\":" + FIRST_STATE +
					"}";
		// @formatter:on

		JSONObject stateObject = getStateObjectByString(stateString);
		JSONArray state = getJSONArrayWithObject(stateObject);

		List<IModule> modules = Lists.newArrayList((IModule) firstModule, (IModule) secondModule);

		// when
		loader.setState(state, modules);

		// then
		assertEquals(stateObject.get(FIRST_IDENTIFIER).isArray(), firstModule.getState());
		assertNull(secondModule.getState());
	}

	public void testSetStateOnTwoModules() {
		// given
		// @formatter:off
				String stateString = "{\"" +
						FIRST_IDENTIFIER + "\":" + FIRST_STATE + ", \"" + 
						SECOND_IDENTIFIER + "\":" + SECOND_STATE + 
					"}";
		// @formatter:on

		JSONObject stateObject = getStateObjectByString(stateString);
		JSONArray state = getJSONArrayWithObject(stateObject);

		List<IModule> modules = Lists.newArrayList((IModule) firstModule, (IModule) secondModule);

		// when
		loader.setState(state, modules);

		// then
		assertEquals(stateObject.get(FIRST_IDENTIFIER).isArray(), firstModule.getState());
		assertEquals(stateObject.get(SECOND_IDENTIFIER).isArray(), secondModule.getState());
	}

	private JSONObject getStateObjectByString(String stateString) {
		JSONObject stateObject = (JSONObject) JSONParser.parseStrict(stateString);
		return stateObject;
	}

	private JSONArray getJSONArrayWithObject(JSONObject stateObject) {
		JSONArray state = new JSONArray();
		state.set(0, stateObject);
		return state;
	}

	public class ModuleMock implements IUniqueModule, IStateful {

		private final String identifier;
		private JSONArray newState;

		public ModuleMock(String identifier) {
			this.identifier = identifier;
		}

		@Override
		@Deprecated
		public List<IModule> getChildren() {
			return null;
		}

		@Override
		public HasChildren getParentModule() {
			return null;
		}

		@Override
		public JSONArray getState() {
			return newState;
		}

		@Override
		public void setState(JSONArray newState) {
			this.newState = newState;
		}

		@Override
		public String getIdentifier() {
			return identifier;
		}
	}
}

@@ -872,16 +872,49 @@
 odule;%0A%0A
+%09private List%3CIModule%3E modules;%0A%0A
 %09@Overri
@@ -916,16 +916,16 @@
 verride%0A
-
 %09public 
@@ -1190,16 +1190,96 @@
 TIFIER);
+%0A%0A%09%09modules = Lists.newArrayList((IModule) firstModule, (IModule) secondModule);
 %0A%09%7D%0A%0A%09pu
@@ -1387,102 +1387,8 @@
 l;%0A%0A
-%09%09List%3CIModule%3E modules = Lists.newArrayList((IModule) firstModule, (IModule) secondModule);%0A%0A
 %09%09//
@@ -1758,102 +1758,8 @@
 );%0A%0A
-%09%09List%3CIModule%3E modules = Lists.newArrayList((IModule) firstModule, (IModule) secondModule);%0A%0A
 %09%09//
@@ -2217,102 +2217,8 @@
 );%0A%0A
-%09%09List%3CIModule%3E modules = Lists.newArrayList((IModule) firstModule, (IModule) secondModule);%0A%0A
 %09%09//
@@ -2696,32 +2696,32 @@
 g(stateString);%0A
+
 %09%09JSONArray stat
@@ -2766,102 +2766,8 @@
 );%0A%0A
-%09%09List%3CIModule%3E modules = Lists.newArrayList((IModule) firstModule, (IModule) secondModule);%0A%0A
 %09%09//

test for ModulesStateLoader (review refactor) YPUB-6018