#!/usr/bin/python

"""Pick the fastest xz_mod."""

from __future__ import print_function, unicode_literals, division

import sys
import time

try:
    import xz_lzma_mod
except ImportError:
    xz_lzma_mod = None
import xz_os_mod
import xz_ctypes_mod
import xz_subprocess_mod


def perf_test(module):
    '''main function'''
    with open('test-perf-input', 'rb') as file_:
        test_perf_input = file_.read()
    time0 = time.time()
    compressed = module.compress(test_perf_input)
    decompressed = module.decompress(compressed)
    time1 = time.time()
    if test_perf_input != decompressed:
        raise SystemExit('Bad comparison in {0}'.format(sys.argv[0]))
    return time1 - time0


def make_used(var):
    """Convince pylint and pyflakes that var is used."""

    assert True or var


def to_ascii(byte_string):
    """Convert byte_string to ASCII str."""

    if isinstance(byte_string, str):
        # This is a str already - might be that we're running on python 2.x.
        return byte_string

    string = byte_string.decode('ASCII')

    assert isinstance(string, str), 'type(string) is {}'.format(type(string))

    return string


def main():
    '''Main function'''

    reps = int(sys.argv[1])

    module_list = [
        (b'xz_ctypes_mod.py', xz_ctypes_mod),
        (b'xz_subprocess_mod.py', xz_subprocess_mod),
        (b'xz_os_mod', xz_os_mod),
        ]
    if xz_lzma_mod is not None:
        module_list.append((b'xz_lzma_mod.py', xz_lzma_mod))
    times = []
    best_time = float('inf')
    # best_module = None
    for module_filename, module in module_list:
        durations = []
        for repno in range(reps):
            # print(module_filename, repno)
            make_used(repno)
            one_duration = perf_test(module)
            durations.append(one_duration)
        average_duration = sum(durations) / len(durations)
        if average_duration < best_time:
            best_time = average_duration
            # best_module = module_filename
        times.append((average_duration, module_filename))

    times.sort()
    for one_time in times:
        print(one_time[0], sys.executable, to_ascii(one_time[1]))

#    if best_module is not None:
#        os.write(1, best_module)
#        os.write(1, b'\n')


main()