from acsploit.options import Options


options = Options()
options.add_option('n_inputs', 10, 'Number of elements to sort')

DESCRIPTION = ('Produces a worst-case input set for mergesort'
               '\n\n  Generates input split up to create maximum comparisons based on'
               'https://stackoverflow.com/questions/24594112/when-will-the-worst-case-of-merge-sort-occur')


def run(generator, output):
    # Worst case for mergesort is a 'separated' list causing maximum comparisons
    output.output(separated_list(generator, options['n_inputs']))


def ascending_list(generator, n_inputs):
    output = [generator.get_min_value()]
    for _ in range(1, n_inputs):
        output.append(generator.get_greater_than(output[-1]))
    return output


def separated_list(generator, n_inputs):
    list = ascending_list(generator, n_inputs)
    separate(list)
    return list


def merge(list, left, right):  # builds 'list' from left and right
    for i in range(len(left)):
        list[i] = left[i]
    for j in range(len(right)):
        list[len(left)+j] = right[j]


def separate(list):  # produces worst case for mergesort from sorted list
    if len(list) < 2:
        return
    if len(list) == 2:
        swap = list[0]
        list[0] = list[1]
        list[1] = swap
        return
    right = list[1::2]
    left = list[0::2]
    separate(left)
    separate(right)
    merge(list, left, right)
