#! /usr/bin/env python3
from __future__ import print_function

import argparse
import os
import sys
import json
import numpy

INDENT = 3
SPACE = " "
NEWLINE = "\n"

def to_json(o, level=0):
    ret = ""
    if isinstance(o, dict):
        ret += "{" + NEWLINE
        comma = ""
        for k,v in o.items():
            ret += comma
            comma = ",\n"
            ret += SPACE * INDENT * (level+1)
            ret += '"' + str(k) + '":' + SPACE
            ret += to_json(v, level + 1)

        ret += NEWLINE + SPACE * INDENT * level + "}"
    elif isinstance(o, str):
        ret += '"' + o + '"'
    elif isinstance(o, list):
        ret += "[" + ",".join([to_json(e, level+1) for e in o]) + "]"
    elif isinstance(o, bool):
        ret += "true" if o else "false"
    elif isinstance(o, int):
        ret += str(o)
    elif isinstance(o, float):
        ret += '%.7g' % o
    elif isinstance(o, numpy.ndarray) and numpy.issubdtype(o.dtype, numpy.integer):
        ret += "[" + ','.join(map(str, o.flatten().tolist())) + "]"
    elif isinstance(o, numpy.ndarray) and numpy.issubdtype(o.dtype, numpy.inexact):
        ret += "[" + ','.join(map(lambda x: '%.7g' % x, o.flatten().tolist())) + "]"
    elif o is None:
        ret += 'null'
    else:
        raise TypeError("Unknown type '%s' for json serialization" % str(type(o)))
    return ret

def get_argument_parser() :
    parser = argparse.ArgumentParser(description="CLI to format a json string pretty but compact")

    parser.add_argument('-i', '--input', help="input file to format", required=True)
    parser.add_argument('-o', '--output', help="output formatted file", nargs='?', const="")

    return parser

if __name__ == '__main__':
    parser = get_argument_parser()
    args = parser.parse_args()

    from pprint import pprint

    with open(args.input) as data_file:    
        data = json.load(data_file)

    dataStr = to_json(data)

    if args.output is None:
        print(dataStr)
    else:
        if args.output == "":
            args.output = args.input

        with open(args.output, "w") as data_file:    
            # pprint(data, data_file)
            data_file.write(dataStr)