import time
from .reformat import *

_DRUGS = [
    'rifampicin', 'isoniazid', 'ethambutol', 'pyrazinamide', 'streptomycin',
    'fluoroquinolones', 'amikacin', 'capreomycin', 'kanamycin',
    'cycloserine',  'ethionamide', 'clofazimine', 'para-aminosalicylic_acid',
    'delamanid', 'bedaquiline', 'linezolid'
]

def lineagejson2text(x):
    textlines = []
    for l in x:
        textlines.append("%(lin)s\t%(family)s\t%(spoligotype)s\t%(rd)s\t%(frac)s" % l)
    return "\n".join(textlines)

def return_fields(obj,args,i=0):
    largs = args.split(".")
    if i+1>len(largs):
        return obj
    sub_obj = obj[largs[i]]
    if isinstance(sub_obj,dict):
        return return_fields(sub_obj,args,i+1)
    elif isinstance(sub_obj,list):
        return [return_fields(x,args,i+1) for x in sub_obj]
    else:
        return sub_obj

def dict_list2text(l,columns = None, mappings = None):
    headings = list(l[0].keys()) if not columns else columns
    rows = []
    header = "\t".join([mappings[x].title() if (mappings!=None and x in mappings) else x.title() for x in headings])
    for row in l:
        r = ",".join([variable2string(return_fields(row,x)) for x in headings])
        rows.append(r)
    str_rows = "\n".join(rows)
    return  "%s\n%s\n" % (header,str_rows)

def dict_list2csv(l,columns = None, mappings = None):
    headings = list(l[0].keys()) if not columns else columns
    rows = []
    header = ",".join([mappings[x].title() if (mappings!=None and x in mappings) else x.title() for x in headings])
    for row in l:
        r = ",".join([variable2string(return_fields(row,x),quote=True) for x in headings])
        rows.append(r)
    str_rows = "\n".join(rows)
    return  "%s\n%s\n" % (header,str_rows)


def variable2string(var,quote=False):
    q = '"' if quote else ""
    if isinstance(var,float):
        return "%.3f" % var
    elif isinstance(var,dict):
        return "%s%s%s" % (q,",".join(list(var)),q)
    elif isinstance(var,list):
        return "%s%s%s" % (q,",".join(var),q)
    else:
        return "%s%s%s" % (q,str(var).replace("_", " "),q)

def load_text(text_strings):
    return r"""
TBProfiler report
=================

The following report has been generated by TBProfiler.

Summary
-------
ID: %(id)s
Date: %(date)s
Strain: %(strain)s
Drug-resistance: %(drtype)s

Lineage report
--------------
%(lineage_report)s

Resistance report
-----------------
%(dr_report)s

Resistance variants report
-----------------
%(dr_var_report)s

Other variants report
---------------------
%(other_var_report)s

Coverage report
---------------------
%(coverage_report)s

Missing positions report
---------------------
%(missing_report)s

Analysis pipeline specifications
--------------------------------
Pipeline version: %(version)s
Database version: %(db_version)s
%(pipeline)s

Disclaimer
----------
This tool is for Research Use Only and is offered free foruse. The London School
of Hygiene and Tropical Medicine shall have no liability for any loss or damages
of any kind, however sustained relating to the use of this tool.

Citation
--------
Coll, F. et al. Rapid determination of anti-tuberculosis drug resistance from
whole-genome sequences. Genome Medicine 7, 51. 2015
""" % text_strings

def load_csv(text_strings):
    return r"""
TBProfiler report
--------------

Summary
-------
ID,%(id)s
Date,%(date)s
Strain,%(strain)s
Drug-resistance,%(drtype)s

Lineage report
--------------
%(lineage_report)s

Resistance report
-----------------
%(dr_report)s

Resistance variants report
-----------------
%(dr_var_report)s

Other variants report
---------------------
%(other_var_report)s

Coverage report
---------------------
%(coverage_report)s

Missing positions report
---------------------
%(missing_report)s

Analysis pipeline specifications
--------------------------------
Pipeline version,%(version)s
Database version,"%(db_version)s"
%(pipeline)s""" % text_strings


def write_text(json_results,conf,outfile,columns = None,reporting_af = 0.0):
    json_results = get_summary(json_results,conf,columns = columns,reporting_af=reporting_af)
    json_results["drug_table"] = [[y for y in json_results["drug_table"] if y["Drug"].upper()==d.upper()][0] for d in _DRUGS]
    for var in json_results["dr_variants"]:
        var["drug"] = ", ".join([d["drug"] for d in var["drugs"]])

    text_strings = {}
    text_strings["id"] = json_results["id"]
    text_strings["date"] = time.ctime()
    text_strings["strain"] = json_results["sublin"]
    text_strings["drtype"] = json_results["drtype"]
    text_strings["dr_report"] = dict_list2text(json_results["drug_table"],["Drug","Genotypic Resistance","Mutations"]+columns if columns else [])
    text_strings["lineage_report"] = dict_list2text(json_results["lineage"],["lin","frac","family","spoligotype","rd"],{"lin":"Lineage","frac":"Estimated fraction"})
    text_strings["dr_var_report"] = dict_list2text(json_results["dr_variants"],["genome_pos","locus_tag","gene","change","freq","drugs.drug"],{"genome_pos":"Genome Position","locus_tag":"Locus Tag","freq":"Estimated fraction"})
    text_strings["other_var_report"] = dict_list2text(json_results["other_variants"],["genome_pos","locus_tag","gene","change","freq"],{"genome_pos":"Genome Position","locus_tag":"Locus Tag","freq":"Estimated fraction"})
    text_strings["coverage_report"] = dict_list2text(json_results["qc"]["gene_coverage"], ["gene","locus_tag","cutoff","fraction"]) if "gene_coverage" in json_results["qc"] else "NA"
    text_strings["missing_report"] = dict_list2text(json_results["qc"]["missing_positions"],["gene","locus_tag","position","position_type","drug_resistance_position"]) if "gene_coverage" in json_results["qc"] else "NA"
    text_strings["pipeline"] = dict_list2text(json_results["pipline_table"],["Analysis","Program"])
    text_strings["version"] = json_results["tbprofiler_version"]
    text_strings["db_version"] = "%s_%s_%s_%s" % (json_results["db_version"]["name"],json_results["db_version"]["commit"],json_results["db_version"]["Author"],json_results["db_version"]["Date"])
    o = open(outfile,"w")
    o.write(load_text(text_strings))
    o.close()



def get_csv_strings(json_results,conf,columns=None):
    json_results = get_summary(json_results,conf,columns = columns)
    json_results["drug_table"] = [[y for y in json_results["drug_table"] if y["Drug"].upper()==d.upper()][0] for d in _DRUGS]
    csv_strings = {}
    csv_strings["id"] = json_results["id"]
    csv_strings["date"] = time.ctime()
    csv_strings["strain"] = json_results["sublin"]
    csv_strings["drtype"] = json_results["drtype"]
    csv_strings["dr_report"] = dict_list2csv(json_results["drug_table"],["Drug","Genotypic Resistance","Mutations"]+columns if columns else [])
    csv_strings["lineage_report"] = dict_list2csv(json_results["lineage"],["lin","frac","family","spoligotype","rd"],{"lin":"Lineage","frac":"Estimated fraction"})
    csv_strings["dr_var_report"] = dict_list2csv(json_results["dr_variants"],["genome_pos","locus_tag","gene","change","freq","drugs.drug"],{"genome_pos":"Genome Position","locus_tag":"Locus Tag","freq":"Estimated fraction"})
    csv_strings["other_var_report"] = dict_list2csv(json_results["other_variants"],["genome_pos","locus_tag","change","freq"],{"genome_pos":"Genome Position","locus_tag":"Locus Tag","freq":"Estimated fraction"})
    csv_strings["coverage_report"] = dict_list2csv(json_results["qc"]["gene_coverage"], ["gene","locus_tag","cutoff","fraction"]) if "gene_coverage" in json_results["qc"] else "NA"
    csv_strings["missing_report"] = dict_list2csv(json_results["qc"]["missing_positions"],["gene","locus_tag","position","position_type","drug_resistance_position"]) if "gene_coverage" in json_results["qc"] else "NA"
    csv_strings["pipeline"] = dict_list2csv(json_results["pipline_table"],["Analysis","Program"])
    csv_strings["version"] = json_results["tbprofiler_version"]
    csv_strings["db_version"] = "%s_%s_%s_%s" % (json_results["db_version"]["name"],json_results["db_version"]["commit"],json_results["db_version"]["Author"],json_results["db_version"]["Date"])
    return csv_strings


def write_csv(json_results,conf,outfile,columns = None):
    csv_strings = get_csv_strings(json_results,conf,columns)
    o = open(outfile,"w")
    o.write(load_csv(csv_strings))
    o.close()
