/**
 * MultiLevelPayload.java
 * Created on Aug 24, 2006
 * (C) Copyright TANDBERG Television Ltd.
 */
package com.tandbergtv.workflow.message;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.tandbergtv.workflow.message.util.AbstractTree;
import com.tandbergtv.workflow.message.util.Scalar;
import com.tandbergtv.workflow.message.util.Tree;

/**
 * MultiLevelPayload is used to store WFS message payload and provides a support for both
 * (key,value) and hierarchical list of (key,value) pairs
 * 
 * @author Vlada Jakobac
 */
public class MultiLevelPayload
{
	private AbstractTree payload;

	/**
	 * Default constructor
	 */
	public MultiLevelPayload()
	{
		super();
		this.payload = new Tree("payload");
	}

	/**
	 * @return Returns the payload.
	 */
	public AbstractTree getPayload()
	{
		return payload;
	}

	/**
	 * @param payload
	 *            The payload to set.
	 */
	public void setPayload(AbstractTree payload)
	{
		this.payload = payload;
	}

	public void putValue(String key, String value)
	{
		// FIXME: here one should check if the key is not already in the list
		AbstractTree newTree = new Tree(key);
		newTree.add(new Scalar(value));
		payload.add(newTree);
	}

	public String getValue(String key)
	{
		Iterator iterator = ((Tree) payload).getTreeList().iterator();
		while (iterator.hasNext())
		{
			AbstractTree absTree = (AbstractTree) iterator.next();
			if (absTree instanceof Tree)
			{
				Tree subtree = (Tree) absTree;
				if (subtree.getKey().equals(key))
				{
					List<AbstractTree> valuePartTree = subtree.getTreeList();
					if (valuePartTree.size() == 1)
					{
						if (valuePartTree.get(0) instanceof Scalar)
						{
							return ((Scalar) valuePartTree.get(0)).getValue();
						}
					}
					else
						return null;
				}
			}
		}
		return null;
	}

	public void putTree(String key, AbstractTree tree)
	{
		AbstractTree newTree = new Tree(key);
		newTree.add(tree);
		payload.add(newTree);
	}

	/*
	 * returns (key,value) pairs that are at the top level hierarchy
	 * 
	 */
	public Map<String, String> getAll()
	{
		Map<String, String> result = new HashMap<String, String>();
		Iterator iterator = ((Tree) payload).getTreeList().iterator();
		while (iterator.hasNext())
		{
			AbstractTree absTree = (AbstractTree) iterator.next();
			if (absTree instanceof Tree)
			{
				Tree subtree = (Tree) absTree;
				String key = subtree.getKey();
				List<AbstractTree> valuePartTree = subtree.getTreeList();
				if (valuePartTree.size() == 1)
				{
					if (valuePartTree.get(0) instanceof Scalar)
					{
						result.put(key, ((Scalar) valuePartTree.get(0)).getValue());
					}
				}
			}
		}
		return result;
	}

	public boolean containsKey(String name)
	{
		Map<String, String> map = getAll();
		return map.containsKey(name);
	}
	
	/**
	 * Removes the (key, value) pair from the payload.
	 * 
	 * @param keyToRemove
	 */
	public void remove(String keyToRemove)
	{
		Iterator iterator = ((Tree) payload).getTreeList().iterator();
		while (iterator.hasNext())
		{
			AbstractTree absTree = (AbstractTree) iterator.next();
			if (absTree instanceof Tree)
			{
				Tree subtree = (Tree) absTree;
				String key = subtree.getKey();
				if (key.equals(keyToRemove))
				{
					iterator.remove();
					break;
				}
			}
		}
		
	}
}
