package org.jcrawler.utils;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Level;
import org.jcrawler.core.PageConnector;
import org.jcrawler.core.base.InjectObject;
import org.jcrawler.core.base.ResultProcessor;
import org.jcrawler.core.entity.Configurator;
import org.jcrawler.core.entity.Page;
import org.jcrawler.core.entity.SelectFieldResult;
import org.jcrawler.core.entity.Selector;
import org.jcrawler.core.selector.QueryParser;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class TestResultKit {

	private TestResultKit() {
	}

	public static final List<String> testResult(String targetUrl, String selector) {
		List<String> results = new ArrayList<String>();
		Page page = new PageConnector().url(targetUrl).connect();
		if (page.getStatus() == Page.FAILED) {
			return null;
		}
		Elements elements = page.getContent().select(selector);
		for (Element element : elements) {
			results.add(element.html());
		}
		return results;
	}

	public static final Object testResult(String targetUrl, String selector, ResultProcessor pageProcessor) {
		Page page = new PageConnector(new Configurator().overtime(10000)).url(targetUrl).connect();
		if (page.getStatus() == Page.FAILED) {
			return Page.FAILED;
		}
		Object result = pageProcessor.process(page, page.getContent().select(selector));
		return result;
	}

	public static final void testResult(String targetUrl, List<Selector> selectors, String preSelector) {
		testResult(targetUrl, selectors, preSelector, InjectObject.class);
	}

	public static final void testResult(String targetUrl, List<Selector> selectors, String preSelector, Class<? extends InjectObject> injectClass) {
		QueryParser.getLogger().setLevel(Level.DEBUG);
		Page page = new PageConnector(new Configurator().overtime(10000)).url(targetUrl).connect();
		if (page.getStatus() == Page.FAILED) {
			System.out.println("Get page content failed");
			return;
		}
		Document doc = page.getContent();
		if (!StringUtils.isEmpty(preSelector)) {
			preSelectProcess(selectors, doc, preSelector, injectClass);
		} else {
			QueryParser qp = new QueryParser(doc, injectClass, selectors).testMode(true);
			List<SelectFieldResult> selectFieldResults = qp.parse();
			printInfo(selectFieldResults);
			if (injectClass != null) {
				InjectObject injectObject = qp.inject(selectFieldResults);
				System.out.println(injectObject);
			}
		}
	}

	private static void preSelectProcess(List<Selector> selectors, Document doc, String preSelector, Class<? extends InjectObject> injectClass) {
		Elements preSelectResult = doc.select(preSelector);
		if (preSelectResult.isEmpty()) {
			return;
		}
		int index = 0;
		for (Element element : preSelectResult) {
			System.out.println("-------------------------------- Element[" + index + "] START --------------------------------");
			System.out.println("----------------------------------------------------------------------------------" + (index >= 10 ? "-" : ""));
			QueryParser qp = new QueryParser(element, injectClass, selectors).testMode(true);
			List<SelectFieldResult> selectFieldResults = qp.parse();
			printInfo(selectFieldResults);
			if (injectClass != null) {
				InjectObject injectObject = qp.inject(selectFieldResults);
				System.out.println(injectObject);
			}
			System.out.println("----------------------------------------------------------------------------------" + (index >= 10 ? "-" : ""));
			System.out.println("-------------------------------- Element[" + index++ + "] END ----------------------------------");
			System.out.println("");
		}
		System.out.println(">>>> Elements count: " + preSelectResult.size());
	}

	private static void printInfo(List<SelectFieldResult> selectFieldResults) {
		for (SelectFieldResult selectFieldResult : selectFieldResults) {
			Selector selector = selectFieldResult.getSelector();
			List<Element> elements = selectFieldResult.getResultElements();
			List<String> selectResult = selectFieldResult.getSelectResult();
			System.out.println("---- Query: [" + selector.getQuery() + "]");
			for (int i = 0; i < elements.size(); i++) {
				System.out.println("--->    Node[" + i + "]: " + elements.get(i));
			}
			System.out.println("---> FieldName: " + selector.getFieldName());
			Class<?> resultType = selectFieldResult.getResultType();
			if (selectResult.size() == 1 && resultType.equals(byte.class) || resultType.equals(short.class) || resultType.equals(int.class)
			        || resultType.equals(long.class) || resultType.equals(float.class) || resultType.equals(double.class)
			        || resultType.equals(Byte.class) || resultType.equals(Short.class) || resultType.equals(Integer.class)
			        || resultType.equals(Long.class) || resultType.equals(Float.class) || resultType.equals(Double.class)) {
				String resultVal = NumberKit.removeNotNumber(selectResult.get(0));
				System.out.println("---> Result: " + resultVal);
			} else {
				System.out.println("---> Result: " + selectResult);
			}
			System.out.println();
		}
	}

}
