#!/usr/bin/env python

# CREATED BY CHRISTOPHER LAVENDER
# BASED ON WORK BY ADAM BURKHOLDER
# INTEGRATIVE BIOINFORMATICS, NIEHS
# WORKING OBJECT ORIENTED VERSION

import os
import argparse
import csv
from operator import itemgetter
from TSScall import readInReferenceAnnotation
from collections import defaultdict


def makeRangesFromAnnotation(annotation):
    ranges = defaultdict(list)
    for entry in annotation:
        ranges[annotation[entry]['chromosome']].append({
            'transcript_id': entry,
            'chromosome': annotation[entry]['chromosome'],
            'start': annotation[entry]['tr_start'],
            'end': annotation[entry]['tr_end'],
            'strand': annotation[entry]['strand'],
            'gene_id': annotation[entry]['gene_id'],
            'tss': annotation[entry]['tss'],
        })
        for field in annotation[entry]['gtf_fields']:
            ranges[annotation[entry]['chromosome']][-1][field] = \
                annotation[entry]['gtf_fields'][field]
    return ranges


def readInClusters(input_detail_file):
    clusters = dict()
    cluster_ranges = defaultdict(list)

    with open(input_detail_file) as f:
        next(f)
        for line in f:
            [
                tss_id,
                tss_type,
                trs,
                genes,
                strand,
                chromosome,
                position,
                reads,
                divergent_flag,
                divergent_partner,
                divergent_distance,
                convergent_flag,
                convergent_partner,
                convergent_distance,
                tss_cluster,
                cluster_members
            ] = line.strip().split('\t')[0:16]

            if tss_cluster != "NA":
                cluster_entry = {
                        'tss_id': tss_id,
                        'tss_type': tss_type,
                        'strand': strand,
                        'chromosome': chromosome,
                        'position': int(position),
                        'reads': int(reads),
                        'cluster_members': cluster_members,
                }

                if tss_cluster in clusters:
                    clusters[tss_cluster].append(cluster_entry)
                else:
                    clusters[tss_cluster] = [cluster_entry]

    for cluster in clusters:
        max_reads = 0
        max_read_entry = None

        cluster_start = float('Inf')
        cluster_end = float('-Inf')

        for entry in clusters[cluster]:
            if entry['tss_type'] == 'called from reference window':
                max_reads = float('Inf')
                max_read_entry = entry
            elif entry['reads'] > max_reads:
                max_reads = entry['reads']
                max_read_entry = entry
            elif entry['reads'] == max_reads:
                if entry['tss_id'] < max_read_entry['tss_id']:
                    max_read_entry = entry
            if cluster_start > entry['position']:
                cluster_start = entry['position']
            if cluster_end < entry['position']:
                cluster_end = entry['position']

        cluster_ranges[max_read_entry['chromosome']].append({
            'cluster_id': cluster,
            'representative_tss_id': max_read_entry['tss_id'],
            'representative_tss_position': max_read_entry['position'],
            'representative_tss_strand': max_read_entry['strand'],
            'cluster_members': max_read_entry['cluster_members'],
            'start': cluster_start,
            'end': cluster_end,
            'chromosome': max_read_entry['chromosome'],