#!/usr/bin/env python

""" MultiQC module to parse output from sequana"""
import os
import re

# prevent boring warning (version 1.0)
import logging
logging.captureWarnings(True)
from multiqc import config
from multiqc.modules.base_module import BaseMultiqcModule
from multiqc.plots import linegraph, table, heatmap, bargraph
logging.captureWarnings(False)

# Initialise the logger
import colorlog
log = colorlog.getLogger(__name__)



class MultiqcModule(BaseMultiqcModule):

    def __init__(self):
        # Initialise the parent object
        super(MultiqcModule, self).__init__(
            name='Sequana/isoseq',    # name that appears at the top
            anchor='sequana_isoseq',  # ??
            target='sequana_isoseq',  # Name show that link to the following href
            href='http://github.com/sequana/sequana/',
            info="pipelines multi Summary")

        self.sequana_data = {}
        for myfile in self.find_log_files("sequana_isoseq"):
            name = myfile['s_name']

            try:
                parsed_data = self.parse_logs(myfile["f"])
            except Exception as err:
                print("{} {} could not be parsed".format(name, myfile['f']))
                print(err)
                continue
            name = parsed_data["s_name"]
            self.sequana_data[name] = parsed_data

        if len(self.sequana_data) == 0:
            log.debug("No samples found: sequana_isoseq")
            raise UserWarning

        info = "<ul>"
        for this in sorted(self.sequana_data.keys()):
            info += '<li><a href="{}/summary.html">{}</a></li>'.format(this,this,this)
        info += "</ul>"
        href="http://sequana.readthedocs.io/en/main/"
        target = "Sequana"
        mname = '<a href="{}" target="_blank">{}</a> individual report pages:'.format(href, target)
        self.intro = '<p>{} {}</p>'.format( mname, info)


        log.info("Found {} reports".format(len(self.sequana_data)))

        self.populate_columns()
        self.add_ccs_reads_section()
        self.add_ccs_mean_length_section()
        self.add_isoforms("hq")
        self.add_isoforms("lq")
        self.add_polyA()
        self.add_primes("three")
        self.add_primes("five")
        self.add_flnc()
        #self.add_ratio_flnc_hq()

    def add_flnc(self):
        data = {}
        for name in self.sequana_data.keys():
            data[name] = {
                'flnc': self.sequana_data[name]["flnc"]
            }
        pconfig = {
            "title": "flnc",
            "logswitch": False,
        }
        self.add_section(
            name = 'Number of flnc',
            anchor = "flnc",
            description = "flnc",
            helptext="",
            plot = bargraph.plot(data, None, pconfig))

    def add_primes(self, label):
        name2 = "{} primes".format(label)
        data = {}
        for name in self.sequana_data.keys():
            data[name] = {
                '3 {}'.format(label):
                    self.sequana_data[name]["{}_primes".format(label)]
            }
        pconfig = {
            "title": name2,
            "logswitch": True,
        }
        self.add_section(
            name = 'Number of {}'.format(name2),
            anchor = name2,
            description = name2,
            helptext="",
            plot = bargraph.plot(data, None, pconfig))

    def add_polyA(self):
        data = {}
        for name in self.sequana_data.keys():
            data[name] = {
                'polyA':
                    self.sequana_data[name]["polyA"]
            }
        pconfig = {
            "title": "polyA",
            "logswitch": True,
        }
        self.add_section(
            name = 'Number of polyA',
            anchor = 'poylA',
            description = 'polyA',
            helptext="",
            plot = bargraph.plot(data, None, pconfig))

    def add_isoforms(self, mode):
        data = {}
        for name in self.sequana_data.keys():
            data[name] = {
                'number_{}_isoforms'.format(mode):
                    self.sequana_data[name]["number_{}_isoforms".format(mode)]
            }
        pconfig = {
            "title": "Number of {} isoforms".format(mode.upper()),
            "logswitch": True,
        }
        self.add_section(
            name = 'Number of {} isoforms'.format(mode.upper()),
            anchor = 'number_{}_isoforms'.format(mode),
            description = 'Number of {} isoforms'.format(mode.upper()),
            helptext="",
            plot = bargraph.plot(data, None, pconfig))

    def add_ccs_reads_section(self):
        data = {}
        for name in self.sequana_data.keys():
            data[name] = {
                'number_ccs_reads': self.sequana_data[name]["number_ccs_reads"]
            }

        pconfig = {
            "title": "Number of CCS reads",
            "percentages": False,
            "min": 100,
            "logswitch": True,
        }
        self.add_section(
            name = 'Number of CCS reads',
            anchor = 'number_ccs_reads',
            description = 'Number of CCS reads',
            helptext = "",
            plot = bargraph.plot(data, None, pconfig))

    def add_ccs_mean_length_section(self):
        data = {}
        for name in self.sequana_data.keys():
            data[name] = {
                'mean': self.sequana_data[name]["mean_length"],
            }
        pconfig = {
                "title": "Mean CCS read length",
            "percentages": False,
            "min": 100,
            "logswitch": True,
        }

        self.add_section(
            name = 'Mean CCS read length',
            anchor = 'mean_ccs_read_length',
            description = 'Mean CCS length of the reads',
            helptext = "",
            plot = bargraph.plot(data, None, pconfig))

    def parse_logs(self, log_dict):
        import json
        log_dict = json.loads(log_dict)
        data = {}
        #data['count'] = log_dict['data']["count"]
        data["mean_length"] = log_dict['data']['CCS']["mean_length"]
        data["number_ccs_reads"] = log_dict['data']['CCS']["number_ccs_reads"]
        data["number_hq_isoforms"] = log_dict['data']['hq_isoform']["N"]
        data["number_lq_isoforms"] = log_dict['data']['lq_isoform']["N"]
        data["flnc"] = log_dict['data']['classification']["full_length_non_chimeric_reads"]
        data["polyA"] = log_dict['data']['classification']["polyA_reads"]
        data["three_primes"] = log_dict['data']['classification']["three_prime_reads"]
        data["five_primes"] = log_dict['data']['classification']["five_prime_reads"]
        #data["ratio_flnc_hq"] = data["flnc"] / data["number_hq_isoforms"]

        data["alldata"] = log_dict
        data["s_name"] = log_dict['sample_name']

        return data

    def populate_columns(self):
        headers = {}
        if any(['mean_length' in self.sequana_data[s] for s in self.sequana_data]):
            headers['mean_length'] = {
                'title': 'CCS mean read length',
                'description': 'CCS mean read length',
                'min': 0,
                'scale': 'RdYlGn',
                'format': '{:,.0d}',
                'shared_key': 'count',
            }

        if any(['number_ccs_reads' in self.sequana_data[s] for s in self.sequana_data]):
            headers["number_ccs_reads"] = {
                'title': 'CCS reads',
                'description': 'Number of CCS reads',
                'min': 0,
                'scale': 'RdYlGn',
                'format': '{:,.0d}'
            }

        for this in ['number_hq_isoforms', 'number_lq_isoforms']:
            if any([this in self.sequana_data[s] for s in self.sequana_data]):
                headers[this] = {
                    'title': " ".join(this.split()),
                    'description': " ".join(this.split()),
                    'min': 0,
                    'scale': 'RdYlGn',
                    'format': '{:,.0d}'
                }
        if any(["polyA" in self.sequana_data[s] for s in self.sequana_data]):
                headers["polyA"] = {
                    'title': "polyA",
                    'description': "",
                    'min': 0,
                    'scale': 'RdYlGn',
                    'format': '{:,.0d}'
                }

        if any(["three_primes" in self.sequana_data[s] for s in self.sequana_data]):
                headers["three_primes"] = {
                    'title': "three prime",
                    'description': "",
                    'min': 0,
                    'scale': 'RdYlGn',
                    'format': '{:,.0d}'
            } 
        if any(["five_primes" in self.sequana_data[s] for s in self.sequana_data]):
                headers["five_primes"] = {
                    'title': "five prime",
                    'description': "",
                    'min': 0,
                    'scale': 'RdYlGn',
                    'format': '{:,.0d}'
            }
        if any(["flnc" in self.sequana_data[s] for s in self.sequana_data]):
                headers["flnc"] = {
                    'title': "flnc",
                    'description': "",
                    'min': 0,
                    'scale': 'RdYlGn',
                    'format': '{:,.0d}'
            }
        if len(headers.keys()):
            self.general_stats_addcols(self.sequana_data, headers)


