#!/usr/bin/python3
import re
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('inputs', nargs='+', help='Input filename')
parser.add_argument('--min_lines', type=int, default=1, help='Specify the min number of lines to rearrange')
args = parser.parse_args()

min_num_lines = args.min_lines

filename_regex = '(src|source|unit_test|include)/.*$'

# caveat: Does fully not handle numbers with different number of digits.
def compare_strs(str1, str2):
    winner = 0 # which one's bigger
    num_sort_mode = False
    for i in range(min(len(str1),len(str2))):
        if winner == 0:
            if str1[i].isdigit() and str2[i].isdigit():
                if num_sort_mode:
                    str1_num += str1[i]
                    str2_num += str2[i]
                else:
                    num_sort_mode = True
                    str1_num = str1[i]
                    str2_num = str2[i]
            elif num_sort_mode:
                if str1[i].isdigit(): str1_num += str1[i]
                if str2[i].isdigit(): str2_num += str2[i]
                winner = int(str1_num) - int(str2_num)
                num_sort_mode = False
                if winner != 0: break
            if str1[i] != str2[i] and not num_sort_mode:
                if str1[i] > str2[i]:
                    winner = 1
                else:
                    winner = -1
    if num_sort_mode: # if it's still in num_sort_mode then find the results
        if len(str1)-1 > i:
            i += 1
            if str1[i].isdigit(): str1_num += str1[i]
        elif len(str2)-1 > i:
            i += 1
            if str2[i].isdigit(): str2_num += str2[i]
        if int(str1_num) > int(str2_num):
            winner = 1
        elif int(str1_num) < int(str2_num):
            winner = -1
        num_sort_mode = False

    if winner == 0:
        if len(str1) != len(str2):
            if len(str1) > len(str2):
                winner = 1
            else:
                winner = -1
    return winner

def cmp_to_key(mycmp):
    'Convert a cmp= function into a key= function'
    class K:
        def __init__(self, obj, *args):
            self.obj = obj
        def __lt__(self, other):
            return mycmp(self.obj, other.obj) < 0
        def __gt__(self, other):
            return mycmp(self.obj, other.obj) > 0
        def __eq__(self, other):
            return mycmp(self.obj, other.obj) == 0
        def __le__(self, other):
            return mycmp(self.obj, other.obj) <= 0
        def __ge__(self, other):
            return mycmp(self.obj, other.obj) >= 0
        def __ne__(self, other):
            return mycmp(self.obj, other.obj) != 0
    return K

def custom_sort(listy):
    for _ in range(len(listy)-1+1):
        for i in range(len(listy)-1):
            bigger = compare_strs(listy[i], listy[i+1])
            if bigger > 0:
                tmp_str = listy[i]
                listy[i] = listy[i+1]
                listy[i+1] = tmp_str
    return listy

# file_lines = [l.strip(stripchars) for l in file_lines]
# currently sorting by first number in filename. smallest numbers first
# this thing may need the ability to recognize filenames
# file_lines = sorted(file_lines, key=lambda line: int(re.search('\d+', line.split('/')[-1] + ' 0').group(0)))
input_filenames=args.inputs
for input_filename in input_filenames:
    with open(input_filename,'r') as file:
        file_lines = file.read().split('\n')
    output_filename=input_filename
    files_range = [] # is a tuple
    filenames_ranges = []
    for i, line in enumerate(file_lines):
        if re.search(filename_regex, line):
            if files_range == []:
                files_range.append(i)
        else:
            if files_range != []:
                files_range.append(i-1)
                # manages min num lines
                if files_range[1] - files_range[0] + 1 >= min_num_lines:filenames_ranges.append(files_range)
                files_range = []
    if files_range != []:
        files_range.append(i-1)
        # manages min num lines
        if files_range[1] - files_range[0] + 1 >= min_num_lines:filenames_ranges.append(files_range)
        files_range = []


    for x in filenames_ranges:
        # accommodate for a close bracket at the end of the last filename
        if file_lines[x[1]][-1] == ')':
            append_chars = ')'
            file_lines[x[1]] = file_lines[x[1]][:-1]
        else:
            append_chars = ''

        new_lines = sorted(file_lines[x[0]:x[1]+1], key=cmp_to_key(compare_strs))
        for i, l in enumerate(range(x[0], x[1]+1)):
            file_lines[l] = new_lines[i]
            if l == x[1]:
                file_lines[l] += append_chars

    with open(output_filename, 'w') as file:
        file.write('\n'.join(file_lines))
