package de.hsadmin.jscli;

import java.util.List;
import java.util.Map;
import java.util.Set;

public class JSONFormatter {
	
	private int indent = 1;

	public String format(Object object) {
		if (object == null) return "";
		if (object instanceof List<?>) {
			return formatList((List<?>) object);
		}
		if (object instanceof Map<?, ?>) {
			return formatMap((Map<?, ?>) object);
		}
		if (object instanceof String) {
			return formatString((String) object);
		}
		if (object instanceof Object[]) {
			return formatArr((Object[]) object);
		}
		return "an instance of " + object.getClass().getCanonicalName();
	}

	public String formatMap(Map<?, ?> map) {
		StringBuffer result = new StringBuffer();
		result.append('{');
		incr();
		result.append(newline());
		StringBuffer formattedMap = new StringBuffer();
		Set<?> keySet = map.keySet();
		for (Object key : keySet) {
			if (formattedMap.length() > 0) {
				formattedMap.append(',');
				formattedMap.append(newline());
			}
			formattedMap.append(key.toString());
			formattedMap.append(':');
			formattedMap.append(format(map.get(key)));
		}
		result.append(formattedMap.toString());
		decr();
		result.append(newline());
		result.append('}');
		return result.toString();
	}
	
	public String formatString(String str) {
		return "'" + str + "'";
	}
	
	public String formatList(List<?> list) {
		return formatArr(list.toArray());
	}
	
	public String formatArr(Object[] arr) {
		StringBuffer result = new StringBuffer();
		result.append('[');
		incr();
		result.append(newline());
		StringBuffer formattedList = new StringBuffer();
		for (int idx = 0; idx < arr.length; idx ++) {
			if (formattedList.length() > 0) {
				formattedList.append(',');
				formattedList.append(newline());
			}
			formattedList.append(format(arr[idx]));
		}
		result.append(formattedList.toString());
		decr();
		if (formattedList.length() > 0) {
			result.append(newline());
		}
		result.append(']');
		return result.toString();
	}
	
	private void incr() {
		indent += 3;
	}

	private void decr() {
		if (indent > 3) {
			indent -= 3;
		}
	}
	
	private String newline() {
		int ind = indent;
		if (ind > 52) {
			ind = 52;
		}
		return "\n                                                   ".substring(0, indent);
	}

}
