import csv, argparse as ap

# Функция для удобства
def distance(s1, e1, s2, e2):
    if s1 <= s2:
        return max(0, s2 - e1)
    else:
        return max(0, s1 - e2)

# Парсинг аргументов
parser = ap.ArgumentParser(description = "Finds several closest neighbours. Gets a number of neighbours to find and CDS's start and end positions as input")
parser.add_argument("filename")
parser.add_argument("-start", type = int, required = True, help = "Start position")
parser.add_argument("-end", type = int, required = True, help = "End position")
parser.add_argument("-output", default = "out.tsv", help = "Output file (default = 'out.tsv')")
parser.add_argument("-n", type = int, default = 3, help = "Number of neighbours to find (default = 3)")

# Создание переменных
args = parser.parse_args()
filename, start, end, output, n = vars(args).values()


with open(filename) as file, open(output, mode = 'w') as out: 
    reader = list(csv.reader(file, delimiter = '\t')) # Чтение файла
    reader_length = len(reader)
    #print(reader[0])
    
    # Создание списка из словарей с нужными мне свойствами. num - номер строки в исходнной таблице, начиная с нуля
    cds_list = [{"num": 0, "start": 0, "end": 0, "distance": 0} for i in range(reader_length)]

    # Заполнение таблицы
    for i in range(reader_length):
        cds_list[i]["num"] = i
        cds_list[i]["start"] = int(reader[i][2])
        cds_list[i]["end"] = int(reader[i][3])
        cds_list[i]["distance"] = distance(start, end, cds_list[i]['start'], cds_list[i]['end'])

    # Сортировка по расстоянию до искомого участка (distance)
    cds_list.sort(key = lambda x: x['distance'])

    # Вывод в выходной файл
    for i in range(reader_length):
        print('\t'.join(reader[cds_list[i]['num']]), file = out)

    print(f'\n\nResult saved in {output}')
    print('\nTop 5 nearest:')
    print('num\tstart\tend\tdistance')
    for i in range(min(reader_length, 5)):
        print(cds_list[i]['num'], cds_list[i]['start'], cds_list[i]['end'], cds_list[i]['distance'])
    

    
    



