package xyz.ignatz.utils;

import java.util.ArrayList;
import java.util.Map;

public class MapToJson {
    public MapToJson(Map<String, Object> map) {
        this.map = map;
    }

    Map<String, Object> map;
    String json;
    int depth;

    public String toJson() {
        if (json == null) {
            json = "";
            depth = 0;
            _print(map);
        }
        return json;
    }

    private void _print(ArrayList<Object> list) {
        _println("[");
        ++depth;
        int c = 0;
        for (Object i : list) {
            if (c++ > 0) _printlnC();
            printV(i);
        }
        _println();
        --depth;
        print("]");
    }

    private void _print(Map<String, Object> map) {
        _println("{");
        ++depth;
        int c = 0;
        for (Map.Entry<String, Object> i : map.entrySet()) {
            if (c++ > 0) _printlnC();
            print(i.getKey(), i.getValue());
        }
        _println();
        --depth;
        print("}");
    }

    private void _print(Object o) {
        if (o instanceof Map) {
            _print((Map<String, Object>)o);
        } else if (o instanceof ArrayList) {
            _print((ArrayList<Object>)o);
        } else if (o instanceof String) {
            _print((String)o);
        } else if (o instanceof Integer) {
            _print(((Integer)o).toString());
        }
    }

    private void print(Object o) {
        String indent = "";
        for (int i = 0; i<depth*4; ++i) {
            indent += " ";
        }
        _print(indent);
        _print(o);
    }

    private void printV(Object o) {
        if (o instanceof String) {
            print(quote((String)o));
        } else {
            print(o);
        }
    }

    private void _printV(Object o) {
        if (o instanceof String) {
            _print(quote((String)o));
        } else {
            _print(o);
        }
    }

    private void println(String str) {
        print(str);
        _println();
    }

    private void _println() {
        _println("");
    }

    private void _print(String str){
        json += str;
    }

    private void _println(String str) {
        _print(str + "\r\n");
    }

    private void print(String key, Object value) {
        print(quote(key));
        _print(": ");
        _printV(value);
    }

    private String quote(String str) {
        return "\"" + str + "\"";
    }

    private void _printlnC() {
        _println(",");
    }
}
