#!/usr/bin/python3
# all arguments to this script are considered as json files
# and attempted to be formatted alphabetically

import json
import os
import re
from sys import argv
from typing import List, Tuple, Union

# Trying to parse JSON comments and then being able to re-insert them into
# the correct location on a re-emitted and sorted JSON would be very difficult.
# To make this somewhat manageable, we take a few shortcuts here:
#
#       - Single-line style comments (//) can be on a new line or at the end of
#         a line with contents.
#
#       - Multi-line style comments (/* */) use the must be free-standing.
#
#       - Comments will get inserted back into the file in the line they came
#         from.  If keys are resorted or the number of lines change, all bets
#         for correctness are off.
#
#       - No attempts to re-indent multi-line comments will be made.
#
# In light of this, it is highly recommended to use a JSON formatter such as
# prettier before using this script and planning to move multi-line comments
# around after key resorting.


class CommentTracker:
    # Regex patterns used.
    single_line_pattern = re.compile(r"\s*//.*$")
    multi_line_start_pattern = re.compile(r"/\*")
    multi_line_end_pattern = re.compile(r".*\*/", re.MULTILINE | re.DOTALL)

    def __init__(self) -> None:
        self.comments: List[Tuple[bool, int, str]] = []

    # Extract out the comments from a JSON-like string and save them away.
    def extract_comments(self, contents: str) -> str:
        result = []

        multi_line_segment: Union[str, None] = None
        multi_line_start = 0

        for idx, line in enumerate(contents.split("\n")):
            single = CommentTracker.single_line_pattern.search(line)
            if single:
                do_append = False if line.startswith(single.group(0)) else True
                line = line[: single.start(0)]
                self.comments.append((do_append, idx, single.group(0)))

            multi_start = CommentTracker.multi_line_start_pattern.search(line)
            if not multi_line_segment and multi_start:
                multi_line_start = idx
                multi_line_segment = line
            elif multi_line_segment:
                multi_line_segment = multi_line_segment + "\n" + line

            if not multi_line_segment:
                result.append(line)
                continue

            multi_end = CommentTracker.multi_line_end_pattern.search(
                multi_line_segment
            )
            if multi_end:
                self.comments.append(
                    (False, multi_line_start, multi_end.group(0))
                )
                result.append(multi_line_segment[multi_end.end(0) :])
                multi_line_segment = None

        return "\n".join(result)

    # Re-insert the saved off comments into a JSON-like string.
    def insert_comments(self, contents: str) -> str:
        result = contents.split("\n")

        for append, idx, string in self.comments:
            if append:
                result[idx] = result[idx] + string
            else:
                result = result[:idx] + string.split("\n") + result[idx:]

        return "\n".join(result)


files = []

for file in argv[1:]:
    if not os.path.isdir(file):
        files.append(file)
        continue
    for root, _, filenames in os.walk(file):
        for f in filenames:
            files.append(os.path.join(root, f))

for file in files:
    if not file.endswith(".json"):
        continue
    print("formatting file {}".format(file))

    comments = CommentTracker()

    with open(file) as fp:
        j = json.loads(comments.extract_comments(fp.read()))

    if isinstance(j, list):
        for item in j:
            item["Exposes"] = sorted(item["Exposes"], key=lambda k: k["Type"])
    else:
        j["Exposes"] = sorted(j["Exposes"], key=lambda k: k["Type"])

    with open(file, "w") as fp:
        contents = json.dumps(
            j, indent=4, sort_keys=True, separators=(",", ": ")
        )

        fp.write(comments.insert_comments(contents))
        fp.write("\n")
