from __future__ import print_function

import argparse
import difflib
import io
import json
import sys
from collections import OrderedDict
from typing import List
from typing import Mapping
from typing import Optional
from typing import Sequence
from typing import Tuple
from typing import Union

from six import text_type


def _get_pretty_format(
        contents, indent, ensure_ascii=True, sort_keys=True, top_keys=(),
):  # type: (str, str, bool, bool, Sequence[str]) -> str
    def pairs_first(pairs):
        # type: (Sequence[Tuple[str, str]]) -> Mapping[str, str]
        before = [pair for pair in pairs if pair[0] in top_keys]
        before = sorted(before, key=lambda x: top_keys.index(x[0]))
        after = [pair for pair in pairs if pair[0] not in top_keys]
        if sort_keys:
            after = sorted(after, key=lambda x: x[0])
        return OrderedDict(before + after)
    json_pretty = json.dumps(
        json.loads(contents, object_pairs_hook=pairs_first),
        indent=indent,
        ensure_ascii=ensure_ascii,
        # Workaround for https://bugs.python.org/issue16333
        separators=(',', ': '),
    )
    # Ensure unicode (Py2) and add the newline that dumps does not end with.
    return text_type(json_pretty) + '\n'


def _autofix(filename, new_contents):  # type: (str, str) -> None
    print('Fixing file {}'.format(filename))
    with io.open(filename, 'w', encoding='UTF-8') as f:
        f.write(new_contents)


def parse_num_to_int(s):  # type: (str) -> Union[int, str]
    """Convert string numbers to int, leaving strings as is."""
    try:
        return int(s)
    except ValueError:
        return s


def parse_topkeys(s):  # type: (str) -> List[str]
    return s.split(',')


def get_diff(source, target):  # type: (str, str) -> str
    source_lines = source.splitlines(True)
    target_lines = target.splitlines(True)
    diff = ''.join(difflib.ndiff(source_lines, target_lines))
    return diff


def main(argv=None):  # type: (Optional[Sequence[str]]) -> int
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--autofix',
        action='store_true',
        dest='autofix',
        help='Automatically fixes encountered not-pretty-formatted files',
    )
    parser.add_argument(
        '--indent',
        type=parse_num_to_int,
        default='2',
        help=(
            'The number of indent spaces or a string to be used as delimiter'
            ' for indentation level e.g. 4 or "\t" (Default: 2)'
        ),
    )
    parser.add_argument(
        '--no-ensure-ascii',
        action='store_true',
        dest='no_ensure_ascii',
        default=False,
        help=(
            'Do NOT convert non-ASCII characters to Unicode escape sequences '
            '(\\uXXXX)'
        ),
    )
    parser.add_argument(
        '--no-sort-keys',
        action='store_true',
        dest='no_sort_keys',
        default=False,
        help='Keep JSON nodes in the same order',
    )
    parser.add_argument(
        '--top-keys',
        type=parse_topkeys,
        dest='top_keys',
        default=[],
        help='Ordered list of keys to keep at the top of JSON hashes',
    )
    parser.add_argument('filenames', nargs='*', help='Filenames to fix')
    args = parser.parse_args(argv)

    status = 0

    for json_file in args.filenames:
        with io.open(json_file, encoding='UTF-8') as f:
            contents = f.read()

        try:
            pretty_contents = _get_pretty_format(
                contents, args.indent, ensure_ascii=not args.no_ensure_ascii,
                sort_keys=not args.no_sort_keys, top_keys=args.top_keys,
            )

            if contents != pretty_contents:
                print('File {} is not pretty-formatted'.format(json_file))

                if args.autofix:
                    _autofix(json_file, pretty_contents)
                else:
                    print(get_diff(''.join(contents), pretty_contents))

                status = 1
        except ValueError:
            print(
                'Input File {} is not a valid JSON, consider using check-json'
                .format(json_file),
            )
            return 1

    return status


if __name__ == '__main__':
    sys.exit(main())
