package org.cloudmeter.model;

import java.io.IOException;
import java.util.LinkedList;

import org.apache.jmeter.testelement.TestElement;
import org.apache.jorphan.collections.HashTree;
import org.apache.jorphan.collections.HashTreeTraverser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

public class HashTreeSerializer extends JsonSerializer<HashTree>  {
	
	private static final Logger log = LoggerFactory.getLogger(HashTreeSerializer.class);

	@Override
	public void serialize(HashTree tree, JsonGenerator generator, SerializerProvider serializer)
			throws IOException, JsonProcessingException {
		
		log.debug("serializing a hash tree.");
		
		
		generator.writeStartObject();
		tree.traverse(new JSonTraverser(generator));
		generator.writeEndObject();
		
	}
	
	class JSonTraverser implements HashTreeTraverser {

		private JsonGenerator jsonGen;
		 private final LinkedList<TestElement> stack = new LinkedList<>();
		
		JSonTraverser(JsonGenerator arg1){
			this.jsonGen = arg1;
		}
		
		@Override
		public void addNode(Object node, HashTree subTree) {
			log.debug("Adding node {} to tree.", node.getClass().getSimpleName());			
			
			stack.addFirst((TestElement) node);
			
			if(isNodeTestBench((TestElement) node)) {
				return;
			}
			
			try {
				jsonGen.writeFieldName("hashTree");
				jsonGen.writeStartObject();
				
				jsonGen.writeFieldName(node.getClass().getName());
				jsonGen.writeObject(node);
				
			} catch (IOException e) {
				
				log.error("Cannot add node {}. Exception type: {}, message {}.",
						node.getClass().getSimpleName(), e.getClass().getName(), e.getMessage());
				if(node instanceof ThreadGroup){
					log.error("Can't make testplan", e);
				}
			}
				

		}

		@Override
		public void subtractNode() {
			log.debug("Subtracting node");
			TestElement ele = this.stack.pop();
			
			if(isNodeTestBench(ele)) {
				return;
			}
			
			try {
				this.jsonGen.writeEndObject();
			} catch (IOException e) {
				log.error("Cannot finish node. Exception type: {}, message {},", 
						e.getClass().getName(), e.getMessage());
			}
		}

		@Override
		public void processPath() {
			log.debug("processing path. ");
//			try {
//				this.jsonGen.writeEndObject();
//			} catch (IOException e) {
//				log.error("Cannot finish hashtree. Exception type: {}, message {},", 
//						e.getClass().getName(), e.getMessage());
//			}
		}
		
	}
	
	
	private boolean isNodeTestBench(TestElement ele) {
		return ele.getPropertyAsString("TestElement.name").equals("WorkBench");
	}


}

@@ -56,87 +56,8 @@
 on;%0A
-import java.util.LinkedList;%0A%0Aimport org.apache.jmeter.testelement.TestElement;
 %0Aimp
@@ -795,19 +795,16 @@
 .%22);%0A%09%09%0A
-%09%09%0A
 %09%09genera
@@ -813,30 +813,29 @@
 r.writeStart
-Object
+Array
 ();%0A%09%09tree.t
@@ -889,30 +889,29 @@
 tor.writeEnd
-Object
+Array
 ();%0A%09%09%0A%09%7D%0A%09%0A
@@ -1000,77 +1000,8 @@
 en;%0A
-%09%09 private final LinkedList%3CTestElement%3E stack = new LinkedList%3C%3E();%0A
 %09%09%0A%09
@@ -1222,254 +1222,49 @@
 %0A%09%09%09
-stack.addFirst((TestElement) node);%0A%09%09%09%0A%09%09%09if(isNodeTestBench((TestElement) node)) %7B%0A%09%09%09%09return;%0A%09%09%09%7D%0A%09%09%09%0A%09%09%09try %7B%0A%09%09%09%09jsonGen.writeFieldName(%22hashTree%22);%0A%09%09%09%09jsonGen.writeStartObject();%0A%09%09%09%09%0A%09%09%09%09jsonGen.writeFieldName(node.getClass().getName());
+try %7B%0A%09%09%09%09jsonGen.writeStartArray();%0A%09%09%09%09
 %0A%09%09%09
@@ -1661,98 +1661,8 @@
 %22);%0A
-%09%09%09TestElement ele = this.stack.pop();%0A%09%09%09%0A%09%09%09if(isNodeTestBench(ele)) %7B%0A%09%09%09%09return;%0A%09%09%09%7D%0A
 %09%09%09%0A
@@ -1691,30 +1691,29 @@
 Gen.writeEnd
-Object
+Array
 ();%0A%09%09%09%7D cat
@@ -1941,362 +1941,19 @@
 %22);%0A
-//%09%09%09try %7B%0A//%09%09%09%09this.jsonGen.writeEndObject();%0A//%09%09%09%7D catch (IOException e) %7B%0A//%09%09%09%09log.error(%22Cannot finish hashtree. Exception type: %7B%7D, message %7B%7D,%22, %0A//%09%09%09%09%09%09e.getClass().getName(), e.getMessage());%0A//%09%09%09%7D%0A%09%09%7D%0A%09%09%0A%09%7D%0A%09%0A%09%0A%09private boolean isNodeTestBench(TestElement ele) %7B%0A%09%09return ele.getPropertyAsString(%22TestElement.name%22).equals(%22WorkBench%22);%0A%09%7D%0A
+%09%09%7D%0A%09%09%0A%09%7D%0A%09
 %0A%0A%7D%0A

save for straight arrays