package jp.sourceforge.asclipse.as3.internal;

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

import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Collection;
import java.util.List;

import jp.sourceforge.asclipse.as3.IAS3Context;
import jp.sourceforge.asclipse.as3.IAS3GlobalContext;
import jp.sourceforge.asclipse.as3.adapter.TypeHierarchyProvider;
import jp.sourceforge.asclipse.as3.adapter.TypeHierarchyProviderTest;
import jp.sourceforge.asclipse.as3.element.AS3Type;
import jp.sourceforge.asclipse.as3.resolver.AS3TypeRef;

import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * シリアライズされたAS3Contextを使ったテストケース。
 * @author shin1ogawa
 */
public class SerializedContextTest {

	static final Logger logger = LoggerFactory.getLogger(SerializedContextTest.class);

	static IAS3GlobalContext globalContext;


	@Test
	public void test01() {
		AS3Type button = findType(globalContext, "mx.controls.Button");
		TypeHierarchyProvider adapterOfButton = new TypeHierarchyProvider(globalContext);
		button.addAdapter(adapterOfButton);
		List<AS3TypeRef> superTypesOfButton = adapterOfButton.getSuperTypes();
		// import mx.core.UIComponent;
		// import mx.core.IDataRenderer;
		// import mx.controls.listClasses.IDropInListItemRenderer;
		// import mx.managers.IFocusManagerComponent;
		// import mx.controls.listClasses.IListItemRenderer;
		// import mx.core.IFontContextComponent;
		// import mx.core.IButton;
		// public class Button extends 
		//   [0]UIComponent implements 
		//   [1]IDataRenderer, [2]IDropInListItemRenderer, [3]IFocusManagerComponent, 
		//   [4]IListItemRenderer, [5]IFontContextComponent, [6]IButton {
		assertThat(superTypesOfButton.size(), is(7));
		AS3TypeRef typeRefOfUIComponent = superTypesOfButton.get(0);
		assertThat(typeRefOfUIComponent.isResolved(), is(true));
		assertThat(typeRefOfUIComponent.getResolvedType().getQualifiedName(),
				is("mx.core.UIComponent"));
		AS3TypeRef typeRefOfIDataRenderer = superTypesOfButton.get(1);
		assertThat(typeRefOfIDataRenderer.isResolved(), is(true));
		assertThat(typeRefOfIDataRenderer.getResolvedType().getQualifiedName(),
				is("mx.core.IDataRenderer"));
		AS3TypeRef typeRefOfIDropInListItemRenderer = superTypesOfButton.get(2);
		assertThat(typeRefOfIDropInListItemRenderer.isResolved(), is(true));
		assertThat(typeRefOfIDropInListItemRenderer.getResolvedType().getQualifiedName(),
				is("mx.controls.listClasses.IDropInListItemRenderer"));
		AS3TypeRef typeRefOfIFocusManagerComponent = superTypesOfButton.get(3);
		assertThat(typeRefOfIFocusManagerComponent.isResolved(), is(true));
		assertThat(typeRefOfIFocusManagerComponent.getResolvedType().getQualifiedName(),
				is("mx.managers.IFocusManagerComponent"));
		AS3TypeRef typeRefOfIListItemRenderer = superTypesOfButton.get(4);
		assertThat(typeRefOfIListItemRenderer.isResolved(), is(true));
		assertThat(typeRefOfIListItemRenderer.getResolvedType().getQualifiedName(),
				is("mx.controls.listClasses.IListItemRenderer"));
		AS3TypeRef typeRefOfIFontContextComponent = superTypesOfButton.get(5);
		assertThat(typeRefOfIFontContextComponent.isResolved(), is(true));
		assertThat(typeRefOfIFontContextComponent.getResolvedType().getQualifiedName(),
				is("mx.core.IFontContextComponent"));
		AS3TypeRef typeRefOfIButton = superTypesOfButton.get(6);
		assertThat(typeRefOfIButton.isResolved(), is(true));
		assertThat(typeRefOfIButton.getResolvedType().getQualifiedName(), is("mx.core.IButton"));
	}

	private AS3Type findType(IAS3GlobalContext context, String qualifiedName) {
		Collection<AS3Type> allTypes = context.getAllTypes();
		for (AS3Type type : allTypes) {
			if (qualifiedName.equals(type.getQualifiedName())) {
				return type;
			}
		}
		return null;
	}

	/**
	 * シリアライズされた{@link IAS3Context}をでシリアライズする。
	 * @throws IOException
	 * @throws ClassNotFoundException
	 */
	@BeforeClass
	public static void setUpBeforeClass() throws IOException, ClassNotFoundException {
		globalContext = new DefaultAS3GlobalContext();
		IAS3Context context = null;
		ObjectInputStream objectInputStream = null;
		try {
			objectInputStream =
					new ObjectInputStream(TypeHierarchyProviderTest.class
						.getResourceAsStream("/builtin.ser"));
			long currentTimeMillis = System.currentTimeMillis();
			logger.debug("builtin.ser 読み込み開始");
			context = (IAS3Context) objectInputStream.readObject();
			logger.debug("builtin.ser 読み込み終了[ms]="
					+ (System.currentTimeMillis() - currentTimeMillis));
			globalContext.addContext(context);
//			Collection<AS3Type> allTypes = context.getAllTypes();
//			int index = 0;
//			for (AS3Type type : allTypes) {
//				System.out.println(++index + ":" + type.getQualifiedName());
//			}
		} finally {
			if (objectInputStream != null) {
				objectInputStream.close();
			}
		}
	}
}
