package jp.sourceforge.cfneo.at4ie2.htmlimpl;

import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import jp.sourceforge.cfneo.at4ie2.BTRuntimeError;
import jp.sourceforge.cfneo.at4ie2.api.test.Context;
import jp.sourceforge.cfneo.at4ie2.api.test.TestCase;
import jp.sourceforge.cfneo.at4ie2.api.test.TestCaseList;
import jp.sourceforge.cfneo.at4ie2.api.test.TestRunner;
import jp.sourceforge.cfneo.at4ie2.api.test.impl.DefaultContext;
import jp.sourceforge.cfneo.at4ie2.api.test.impl.DefaultTestCaseList;
import jp.sourceforge.cfneo.at4ie2.utils.TestUtil;

import org.apache.log4j.Logger;
import org.cyberneko.html.parsers.DOMParser;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

public class HtmlTestRunner implements TestRunner {

	Logger logger = Logger.getLogger(HtmlTestRunner.class);
	Context context;
	TestCaseList testCaseList;

	public HtmlTestRunner(Context context, String filepath) {
		this.context = context;
		this.createTestCaseList(filepath);
	}

	protected void createTestCaseList(String filepath) {
		this.testCaseList = new DefaultTestCaseList(context);
		List<String> list = this.parseSeleniumTestCase(filepath);
		int id = 0;
		for (String line: list) {
			id++;
			// TODO なんだかすごくおっかない
			if ("test,".equals(line) == false) {
				TestUtil.appendTestCase(context, testCaseList, id, line);
			}
		}
	}

	protected List<String> parseSeleniumTestCase(String filepath) {
		try {
			List<String> list = new ArrayList<String>();
			DOMParser parser = new DOMParser();
			parser.parse(new InputSource(
					new InputStreamReader(new FileInputStream(filepath), "UTF-8")));
			Document doc = parser.getDocument();
			this.searchTestCase(list, doc.getDocumentElement());
			return list;
		} catch (Exception e) {
			throw new BTRuntimeError(e);
		}
	}

	private void searchTestCase(List<String> list, Element element) {
		String tag = element.getTagName();
		if ("LINK".equals(tag)) {
			// TODO baseUrlをストレージ領域にセットしないといかんかも。
		} else if ("TR".equals(tag)) {
			NodeList items = element.getChildNodes();
			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < items.getLength(); i++) {
				Node item = items.item(i);
				if (item.getNodeType() == Node.ELEMENT_NODE) {
					Element itemElement = (Element) item;
					if ("TD".equals(itemElement.getTagName())
							&& itemElement.hasChildNodes()) {
						String s = itemElement.getFirstChild().getNodeValue().trim();
						if (s != null) {
							sb.append(s);
							sb.append(",");
						}
					}
				}
			}
			list.add(sb.toString());
		} else {
			NodeList items = element.getChildNodes();
			for (int i = 0; i < items.getLength(); i++) {
				if (items.item(i).getNodeType() == Node.ELEMENT_NODE) {
					searchTestCase(list, (Element) items.item(i));
				}
			}
		}
	}

	@Override
	public void run() {
		try {
			DefaultContext.getInstance().getResultLogger().resetLog();
			for (int row = 0; row < this.testCaseList.size(); row++) {
				TestCase testCase = this.testCaseList.getTestCase(row);
				logger.debug(testCase);
				if (this.context.isToolTest() == false) {
					testCase.doTest();
				}
			}
		} catch (BTRuntimeError e) {
			DefaultContext.getInstance().getResultLogger().writeResult(e.getMessage());
			throw e;
		} finally {
			logger.info("******************************");
			logger.info("***** Result log - start *****");
			logger.info(DefaultContext.getInstance().getResultLogger().readResult());
			logger.info("***** Result log - end   *****");
			logger.info("******************************");
		}
	}

}
