import os
import sys
import shutil
import argparse

def read_permutations(handle):
	line = [l.strip() for l in handle if l.strip()]
	i = 0
	perm = []
	while i < len(line):
		id = line[i][1:]
		body = line[i + 1].split()
		body = [int(n) for n in body[:-1]]
		perm.append((id, body))
		i += 2
	return perm

def reverse_permutation(permutation):
	ret = [-x for x in permutation]
	ret.reverse()
	return ret

def match(reference, query):
	m = len(query)
	n = len(reference)
	for i in xrange(0, n - m + 1):
		matching = zip(reference[i:i + n], query)
		matching = (a[0] == a[1] for a in matching)
		if sum(matching) == m:
			return True
	return False

def get_headers(file_name):
	return [l[1:] for l in open(file_name, 'r') if l and l[0] == '>']

def is_reference_permutation(reference_header, now_header):
	return [header for header in reference_header if now_header in header] != []

def depict_visible_sequences(unmapped_config_path, seq):
	unmapped_config_handle = open(unmapped_config_path, 'a')
	print >> unmapped_config_handle, 'chromosomes =', ';'.join(seq)
	print >> unmapped_config_handle,'chromosomes_display_default = no'
	unmapped_config_handle.close()

default_out_config = 'unmapped.circos.conf'
default_out_config_path = os.path.join('<input_folder>', 'circos', default_out_config)
parser = argparse.ArgumentParser(description='A script that hides all perfectly mapped contigs on the circos picture.',
				formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('input_folder', help='Path to folder with files generated by Sibelia/C-Sibelia')
parser.add_argument('reference', help='Path to FASTA file with the reference')
parser.add_argument('-o', '--out_config', help='File name where sorted config is stored', 
			default=default_out_config_path)
parser.add_argument('-i', '--in_config', help='File name of the input config', default='circos.conf')
args = parser.parse_args()

input_folder = args.input_folder
circos_folder = os.path.join(args.input_folder, 'circos')
out_config = os.path.join(circos_folder, default_out_config) if args.out_config == default_out_config_path else args.out_config
permutations_file = os.path.join(args.input_folder, 'genomes_permutations.txt')
reference_header = get_headers(args.reference)

leave = []
perm = read_permutations(open(permutations_file, 'r'))
reference_perm = [p for p in perm if is_reference_permutation(reference_header, p[0])]
reference_perm_header = [p[0] for p in reference_perm]

for p in perm:
	header, body = p
	if not header in reference_perm_header:
		positive_query = body
		negative_query = reverse_permutation(positive_query)
		matching = [reference[0] for reference in reference_perm if match(reference[1], positive_query) or match(reference[1], negative_query)]
		if matching == []:
			leave.append(header)


config = os.path.join(circos_folder, args.in_config)
karyotype = os.path.join(circos_folder, 'circos.sequences.txt')

id_to_seq = dict()
line = [l.strip() for l in open(karyotype, 'r') if l.strip() != '']
for l in line:
	l = l.split()
	id_to_seq[l[3]] = l[2]

unmapped_seq = [id_to_seq[header] for header in leave]
reference_seq = [id_to_seq[header] for header in reference_perm_header]
new_config_seq = [unmapped_seq] + [[seq] for seq in unmapped_seq]
new_config_file = [out_config] + [os.path.join(circos_folder, seq[0] + '.circos.conf') for seq in new_config_seq[1:]]

for i in xrange(len(new_config_seq)):
	shutil.copy(config, new_config_file[i])
	depict_visible_sequences(new_config_file[i], new_config_seq[i] + reference_seq)
	
	