package jp.sourceforge.asclipse.as3.adapter;

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

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import jp.sourceforge.asclipse.as3.ParserUtil;
import jp.sourceforge.asclipse.as3.ParserUtilTest;
import jp.sourceforge.asclipse.as3.ParserUtil.AS3ParserException;
import jp.sourceforge.asclipse.as3.element.AS3Element;
import jp.sourceforge.asclipse.as3.element.AS3Root;

import org.antlr.runtime.RecognitionException;
import org.apache.commons.lang.StringUtils;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

	private static final Logger LOGGER = LoggerFactory.getLogger(OutlineProviderTest.class);


	/**
	 * @throws IOException
	 * @throws RecognitionException
	 * @throws AS3ParserException
	 */
	@Test
	public void sample06() throws IOException, RecognitionException, AS3ParserException {
		final String asFileName = "/Sample06.as";
		LOGGER.info("parse start: " + asFileName);
		InputStream input = ParserUtilTest.class.getResourceAsStream(asFileName);
		assertThat(input, notNullValue());
		AS3Root rootElement = ParserUtil.parse(input, asFileName);
		// DebugUtil.debugAS3Element(rootElement, 0);
		OutlineProvider adapter = new OutlineProvider(null);
		rootElement.addAdapter(adapter);
		debugOutline(rootElement, 0);
		//		[0]import p1.*;
		//		[1]import p1.Class1;
		//		[2]import p1.p2.*;
		//		[3]class Sample06 {
		//			[0]public namespace mynamespace1;
		//			[1]public namespace mynamespace2 = "http://www.shin1ogawa.com/mynamespace2";
		//			[2]var property01:int;
		//			[3]var property02:int;
		//			[4]var property03:int = 10;
		//			[5]mynamespace1 var property03:int = 0;
		//			[6]private var property04:int =10;
		//			[7]public const property05:int = 10;
		//			[8]public static var property06:int = 10;
		//			[9],[10]public var property07:int = 10, property08:Function;
		//			[11]function func01() {}
		//			[12]public function func02() {}
		//			[13]public static function func03() {}
		//			[14]public function func04():void {}
		//			[15]public function func05(arg1:String):void {}
		//			[16]private function func06(arg1:String, arg2:int):void {}
		//			[17]public function func07(arg1, arg2:int):void {} 
		//			[18]mynamespace2 function func07():void {}
		//			[19]public function set func08(arg1:int) {
	}

	private static void debugOutline(AS3Element parent, int depth) {
		String indent = StringUtils.repeat("\t", depth);
		OutlineProvider adapter = parent.getAdapter(OutlineProvider.class);
		assertThat(adapter, notNullValue());
		LOGGER.debug(String.format("[%5d,%3d]-[%5d,%3d]%s%s,parent=%s, isLeaf=%s", parent
			.getStartLine(), parent.getCharPositionInLine(), parent.getEndLine(), parent
			.getEndCharPositionInLine(), indent, parent.getTitle(),
				(adapter.getOutlineParent() != null ? adapter.getOutlineParent().getOutlineTitle()
						: "null"), String.valueOf(adapter.isLeaf())));
		if (!adapter.isLeaf()) {
			List<AS3Element> children = adapter.getOutlineChildren();
			for (AS3Element child : children) {
				debugOutline(child, depth + 1);
			}
		}
	}
}
