#!/usr/bin/env python3
import io
import json
import re
import sys

from collections import OrderedDict


def extract_numbers(s):
    """
    >>> extract_numbers("CLK_HROW_WR10END2_3")
    ('CLK_HROW_WR', 10, 'END', 2, '_', 3)
    >>> extract_numbers("VBRK_WR1END2")
    ('VBRK_WR', 1, 'END', 2)
    """
    bits = []
    for m in re.finditer("([^0-9]*)([0-9]*)", s):
        if m.group(1):
            bits.append(m.group(1))
        if m.group(2):
            bits.append(int(m.group(2)))
    return tuple(bits)


def sort(data):
    """Sort data types via "natural" numbers.

    Supports all the basic Python data types.
    >>> o = sort({
    ...    't1': {'c','b'},          # Set
    ...    't2': ('a2', 'a10', 'e'), # Tuple
    ...    't3': [5, 3, 2],          # List
    ...    't4': {                   # Dictionary
    ...        'a4': ('b2', 'b3'),
    ...        'a2': ['c1', 'c2', 'c0', 'c10'],
    ...    },
    ...    't5': ['a1b5', 'a2b1', 'a1b1'],
    ... })
    >>> for t in o:
    ...    print(t+':', o[t])
    t1: ('b', 'c')
    t2: ('a2', 'a10', 'e')
    t3: (5, 3, 2)
    t4: OrderedDict([('a2', ('c1', 'c2', 'c0', 'c10')), ('a4', ('b2', 'b3'))])
    t5: ('a1b5', 'a2b1', 'a1b1')

    Don't mangle "pairs"
    >>> sort([('b', 'c'), ('2', '1')])
    (('b', 'c'), ('2', '1'))
    """

    def key(o):
        if o is None:
            return None
        elif isinstance(o, str):
            return extract_numbers(o)
        elif isinstance(o, int):
            return o
        elif isinstance(o, (list, tuple)):
            return tuple(key(i) for i in o)
        elif isinstance(o, dict):
            return tuple((key(k), key(v)) for k, v in o.items())
        elif isinstance(o, set):
            return tuple(key(k) for k in o)
        raise ValueError(repr(o))

    def rsorter(o):
        if isinstance(o, dict):
            nitems = []
            for k, v in o.items():
                nitems.append((key(k), k, rsorter(v)))
            nitems.sort(key=lambda n: n[0])

            new_dict = OrderedDict()
            for _, k, v in nitems:
                new_dict[k] = v
            return new_dict

        elif isinstance(o, set):
            return tuple(sorted((rsorter(v) for v in o), key=key))
        elif isinstance(o, (tuple, list)):
            return tuple(rsorter(v) for v in o)
        else:
            return o

    return rsorter(data)


def pprint(f, data):
    detach = False
    if not isinstance(f, io.TextIOBase):
        detach = True
        f = io.TextIOWrapper(f)
    data = sort(data)
    json.dump(data, f, indent=4)
    f.write('\n')
    f.flush()
    if detach:
        f.detach()


if __name__ == "__main__":
    if len(sys.argv) == 1:
        import doctest
        doctest.testmod()
    else:
        assert len(sys.argv) == 2
        d = json.load(open(sys.argv[1]))
        pprint(sys.stdout, d)
