from flask import Flask, Response
from flask_restful import Resource, Api
from cendr import api
from cendr.models import report, mapping, strain
from collections import OrderedDict
import decimal
import json
import datetime
import os, sys


FIELDS = ["strain", "isotype", "warning_message", "use", "sequenced", "previous_names", "source_lab", "latitude","longitude", "landscape", "substrate", "isolated_by", "isolation_date", "isolation_date_comment", "isolation","location", "address", "city", "state", "country", "set_heritability", "set_1", "set_2", "set_3", "set_4","bam_file", "bam_index", "cram_file", "cram_index", "variant_file"]
PEWEE_FIELDS_LIST = [strain.strain, strain.isotype, strain.warning_message, strain.use, strain.sequenced, strain.previous_names, strain.source_lab, strain.latitude, strain.longitude, strain.landscape, strain.substrate, strain.isolated_by, strain.isolation_date, strain.isolation_date_comment, strain.isolation, strain.location, strain.address, strain.city, strain.state, strain.country, strain.set_heritability, strain.set_1, strain.set_2, strain.set_3, strain.set_4, strain.bam_file, strain.bam_index, strain.cram_file, strain.cram_index, strain.variant_file]


class CustomEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, decimal.Decimal):
            return float(o)
        if isinstance(o, datetime.date):
            return "G"
        return super(CustomEncoder, self).default(o)

def abort_if_todo_doesnt_exist(request_id):
    if request_id not in TODOS:
        abort(404, message="Doesn't exist".format(request_id))

class mapping_api(Resource):
    def get(self):
        reports = list(mapping.select(mapping.chrom, 
                                      mapping.pos,
                                      mapping.interval_start,
                                      mapping.interval_end,
                                      mapping.log10p,
                                      mapping.variance_explained,
                                      mapping.BF,
                                      mapping.reference,
                                      mapping.version).join(report).filter(report.release==0).tuples().execute())
        
        fields = ["chrom", "pos", "interval_start", "interval_end", "log10p", "variance_explained", "BF", "reference", "version"]
        reports = [OrderedDict(zip(fields, x)) for x in reports]
        dat = json.dumps(reports, cls=CustomEncoder, indent = 4)
        return Response(response=dat, status=200, mimetype="application/json")

class strain_api(Resource):
    def get(self):
        strain_data = list(strain.select(*PEWEE_FIELDS_LIST).tuples().execute())
        strain_data = [OrderedDict(zip(FIELDS, x)) for x in strain_data]
        dat = json.dumps(strain_data, cls=CustomEncoder, indent = 4)
        return Response(response=dat, status=200, mimetype="application/json")


class strain_ind_api(Resource):
    def get(self, strain_name):
        strain_data = list(strain.select(*PEWEE_FIELDS_LIST).filter(strain.strain == strain_name).tuples().execute())
        strain_data = OrderedDict(zip(FIELDS, strain_data[0]))
        dat = json.dumps(strain_data, cls=CustomEncoder, indent = 4)
        return Response(response=dat, status=200, mimetype="application/json")

class isotype_ind_api(Resource):
    def get(self, isotype_name):
        strain_data = list(strain.select(*PEWEE_FIELDS_LIST).filter(strain.isotype == isotype_name).tuples().execute())
        strain_data = OrderedDict(zip(FIELDS, strain_data[0]))
        dat = json.dumps(strain_data, cls=CustomEncoder, indent = 4)
        return Response(response=dat, status=200, mimetype="application/json")



api.add_resource(mapping_api, '/api/mapping/')
api.add_resource(strain_api, '/api/strain/')
api.add_resource(strain_ind_api, '/api/strain/<string:strain_name>/')
api.add_resource(isotype_ind_api, '/api/isotype/<string:isotype_name>/')

@@ -248,397 +248,73 @@
  = %5B
-%22strain%22, %22isotype%22, %22warning_message%22, %22use%22, %22sequenced%22, %22previous_names%22, %22source_lab%22, %22latitude%22,%22longitude%22, %22landscape%22, %22substrate%22, %22isolated_by%22, %22isolation_date%22, %22isolation_date_comment%22, %22isolation%22,%22location%22, %22address%22, %22city%22, %22state%22, %22country%22, %22set_heritability%22, %22set_1%22, %22set_2%22, %22set_3%22, %22set_4%22,%22bam_file%22, %22bam_index%22, %22cram_file%22, %22cram_index%22, %22variant_file
+x.name for x in strain._meta.sorted_fields if x.name != %22id
 %22%5D%0APE
+E
 WEE_
@@ -332,550 +332,88 @@
  = %5B
-strain.strain, strain.isotype, strain.warning_message, strain.use, strain.sequenced, strain.previous_names, strain.source_lab, strain.latitude, strain.longitude, strain.landscape, strain.substrate, strain.isolated_by, strain.isolation_date, strain.isolation_date_comment, strain.isolation, strain.location, strain.address, strain.city, strain.state, strain.country, strain.set_heritability, strain.set_1, strain.set_2, strain.set_3, strain.set_4, strain.bam_file, strain.bam_index, strain.cram_file, strain.cram_index, strain.variant_file
+getattr(strain, x.name) for x in strain._meta.sorted_fields if x.name != %22id%22
 %5D%0A%0A
-%0A
 clas
@@ -1850,32 +1850,33 @@
 train.select(*PE
+E
 WEE_FIELDS_LIST)
@@ -2219,32 +2219,33 @@
 train.select(*PE
+E
 WEE_FIELDS_LIST)
@@ -2572,32 +2572,32 @@
  isotype_name):%0A
-
         strain_d
@@ -2624,16 +2624,17 @@
 lect(*PE
+E
 WEE_FIEL

clean up api