package com.pmease.quickbuild.plugin.report.boosttest;

import java.util.Collections;
import java.util.List;
import java.util.Vector;

import org.dom4j.Element;

import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.pmease.quickbuild.plugin.report.engine.datatype.DataTypes;
import com.pmease.quickbuild.plugin.report.engine.generator.AbstractProcessor;
import com.pmease.quickbuild.plugin.report.xunit.XUnitCategory;
import com.pmease.quickbuild.plugin.report.xunit.generator.AbstractTestProcessor;
import com.pmease.quickbuild.plugin.report.xunit.generator.TestStatus;

public class BoostTestCategory extends XUnitCategory {

	private static final long serialVersionUID = 1L;

	@Override
	public String getId() {
		return "boost";
	}

	@Override
	public String getName() {
		return "Boost Test";
	}

	@Override
	protected AbstractProcessor getTestProcessor() {
		return new AbstractTestProcessor(this) {

			private static final long serialVersionUID = 1L;

			@Override
			public String getXPathOfTestCase() {
				return "//TestCase";
			}

			@Override
			protected String getSuiteName(Element node) {
				Element root = node.getDocument().getRootElement();
				Element parent = node.getParent();
				Vector<String> v = new Vector<String>();
				
				while (parent != null && parent != root) {
					String name = parent.attributeValue("name");
					v.add(name);
					parent = parent.getParent();
				}
				
				Collections.reverse(v);
				
				return Joiner.on("::").skipNulls().join(v);
			}

			@Override
			protected String getTestName(Element node) {
				return node.attributeValue("name");
			}

			@Override
			protected TestStatus getStatus(Element node) {
				TestStatus status = TestStatus.PASS;
				
				if (node.elements("Error").size() > 0 || node.elements("FatalError").size() > 0 || node.elements("Exception").size() > 0) {
					status = TestStatus.FAIL;
				}
				
				return status;
			}

			@Override
			protected long getDuration(Element node) {
				Element e = node.element("TestingTime");
				if (e != null) {
					// See http://track.pmease.com/browse/QB-1269
					Long d = (Long) DataTypes.LONG.fromString(e.getText(), null);
					if (d != null) {
						d /= 1000L;
						return d;
					}
				}
				
				return 0;
			}

			@Override
			protected List<String> getErrorTypes(Element node) {
				List<String> list = Lists.newArrayList();
				
				for (Object each : node.elements("Exception")) {
					Element n = (Element) each;
					list.add("Exception at [" + n.attributeValue("file") 
							+ ", line: " + n.attributeValue("line") + "]");
				}
				
				for (Object each : node.elements("FatalError")) {
					Element n = (Element) each;
					list.add("FatalError at [" + n.attributeValue("file") 
							+ ", line: " + n.attributeValue("line") + "]");
				}
				
				for (Object each : node.elements("Error")) {
					Element n = (Element) each;
					list.add("Error at [" + n.attributeValue("file") 
							+ ", line: " + n.attributeValue("line") + "]");
				}
				
				return list;
			}

			@Override
			protected List<String> getErrorMessages(Element node) {
				List<String> list = Lists.newArrayList();
				
				for (Object each : node.elements("Exception")) {
					Element n = (Element) each;
					list.add(n.getText());
				}
				
				for (Object each : node.elements("FatalError")) {
					Element n = (Element) each;
					list.add(n.getText());
				}
				
				for (Object each : node.elements("Error")) {
					Element n = (Element) each;
					list.add(n.getText());
				}
				
				return list;
			}

			@Override
			protected List<String> getMessages(Element node) {
				List<String> list = Lists.newArrayList();
				
				for (Object each : node.elements("Message")) {
					Element n = (Element) each;
					list.add( n.getText() + " - at [" + n.attributeValue("file") 
							+ ", line: " + n.attributeValue("line") + "]");
				}
				
				return list;
			}
		};
	}
}
