package jp.sourceforge.asclipse.as3.internal;

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

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;

import jp.sourceforge.asclipse.as3.IAS3Context;
import jp.sourceforge.asclipse.as3.IAS3GlobalContext;
import jp.sourceforge.asclipse.as3.ParserUtil;
import jp.sourceforge.asclipse.as3.ParserUtil.AS3ParserException;
import jp.sourceforge.asclipse.as3.element.AS3Root;
import jp.sourceforge.asclipse.as3.resolver.AS3TypeRef;

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

/**
 * {@link DefaultAS3Context}のテストケース。
 * @author shin1ogawa
 */
public class DefaultAS3ContextTest {

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

	static IAS3GlobalContext globalContext;


	@Test
	public void test01() {
		final String qualifiedName = "ArgumentError";
		AS3TypeRef typeRef = globalContext.getTypeResolver().newTypeRef(qualifiedName);
		assertThat(globalContext.resolve(typeRef, null), is(true));
		assertThat(typeRef.isResolved(), is(true));
	}

	@Test
	public void test02() {
		final String qualifiedName = "mx.controls.Button";
		AS3TypeRef typeRef = globalContext.getTypeResolver().newTypeRef(qualifiedName);
		assertThat(globalContext.resolve(typeRef, null), is(true));
		assertThat(typeRef.isResolved(), is(true));
	}

	@Test
	public void test03() {
		final String qualifiedName = "Detarame";
		AS3TypeRef typeRef = globalContext.getTypeResolver().newTypeRef(qualifiedName);
		assertThat(globalContext.resolve(typeRef, null), is(false));
		assertThat(typeRef.isResolved(), is(false));
	}

	/**
	 * ビルトインクラス類を取り込む。
	 * @throws FileNotFoundException
	 * @throws AS3ParserException
	 */
	@BeforeClass
	public static void setUpBeforeClass() throws FileNotFoundException, AS3ParserException {
		globalContext = new DefaultAS3GlobalContext();
		for (String folderName : new String[] {
			"src/main/resources/as/",
			// とりあえずmx.controlsだけ
			"src/main/resources/as/mx/controls/"
		}) {
			List<AS3Root> elements = parseDirectlyUnderFiles(new File(folderName));
			IAS3Context as3context = new DefaultAS3Context(folderName);
			for (AS3Root root : elements) {
				as3context.addAS3Root(root);
			}
			globalContext.addContext(as3context);
		}
	}

	/**
	 * フォルダ直下のasファイルを解析、ツリーを構築し、構築したツリーのリストを返す。
	 * @param rootFolder
	 * @return 構築したツリーのリスト
	 */
	public static List<AS3Root> parseDirectlyUnderFiles(File rootFolder) {
		File[] listFiles = rootFolder.listFiles(new FileFilter() {

			public boolean accept(File pathname) {
				return !pathname.isDirectory() && pathname.getAbsolutePath().endsWith(".as");
			}
		});
		List<AS3Root> rootElements = new ArrayList<AS3Root>(listFiles.length);
		for (File file : listFiles) {
			String resourceName =
					file.getAbsolutePath().replaceFirst(rootFolder.getAbsolutePath(), "");
			AS3Root root = null;
			try {
				root = ParserUtil.parse(new FileInputStream(file), resourceName);
				rootElements.add(root);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (AS3ParserException e) {
				e.printStackTrace();
			}
			assertThat(root, notNullValue());
			assertThat(root.hasParserError(), is(false));
		}
		return rootElements;
	}
}
