#!/usr/bin/python2.7

import unittest,os,csv,pdb

class test_idata(unittest.TestCase):

    cfg = os.path.join(os.getcwd(),'grapeipm.cfg')    
    inp = os.path.join(os.getcwd(),'idata')
    oup = os.path.join(os.getcwd(),'odata','out.dat')

    cmd = '../convert.py '+cfg+' -i'+inp+os.path.sep+'%s -o'+oup+' -w -s \'%s\' -e \'%s\''

    # check the following given a run case
    #    there are the correct number of output data points
    #    each row has the correct number of entries
    #    the hydrocodes are valid
    #    the interval entries are correct
    #    the record numbers are valid
    #    based on the hydrocode, NULL appears where it should
    #     for a few manually specified points, confirm output
    def check_rowcount_rowlength_hydrocode_interval_nulls_records(self,ifile,s,e,rl,hcs,rcs,nulls,i,dc,pcs):
        pointchecks = {}
        for p,cs in pcs:pointchecks[p] = (cs,[False for x in cs])
        recordchecks = [False for x in rcs[1]]
        os.system(self.cmd % (ifile,s,e))
        with open(self.oup,'r') as ofh:
            reader = csv.reader(ofh)
            headers = next(reader)
            j = 1
            for orow in reader:
                self.assertEqual(len(orow),rl)
                self.assertEqual(str(i),orow[-2])
                self.assertTrue(orow[-1] in hcs)
                null = nulls[hcs.index(orow[-1])]
                for n in null:self.assertEqual(orow[n],'NULL')
                record = int(orow[rcs[0]])
                self.assertTrue(record in rcs[1])
                recordchecks[rcs[1].index(record)] = True
                if record in pointchecks:
                    try:
                        dpoint = ','.join(orow)
                        self.assertTrue(dpoint in pointchecks[record][0])
                        pointchecks[record][1][pointchecks[record][0].index(dpoint)] = True
                    except AssertionError:
                        print(','.join(orow))
                        print(pointchecks[record])
                        raise AssertionError
                j += 1
            try:
                self.assertFalse(False in recordchecks)
            except AssertionError:
                print('missing records:')
                print([x for x,i in zip(rcs[1],recordchecks) if not i])
                raise AssertionError
            self.assertEqual(j,dc)
            for record in pointchecks:
                self.assertFalse(False in pointchecks[record][1])

    def test_SPAREC(self):
        ifile = 'SPAREC_Min15.dat'
        start,end = '2014-9-30 23:59:59','2014-10-5 00:00:00'
        hydrocodes = ('SPAREC_air','SPAREC_canopy')
        nulls = (2,),(2,)
        records = (1,list(range(12699,13082+1)))
        interval = 15
        rowlength = 12
        datapoints = 1+2*4*24*4
        pointchecks = (
            (12699,(
                '2014-10-01 00:00:00,12699,NULL,17.14087,99.998,348.8169,0,0,15,0,15,SPAREC_air',
                '2014-10-01 00:00:00,12699,NULL,16.9258,99.998,434.8222,0,0,15,0,15,SPAREC_canopy',
                )),
                )
        self.check_rowcount_rowlength_hydrocode_interval_nulls_records(
            ifile,start,end,rowlength,hydrocodes,records,nulls,interval,datapoints,pointchecks)

    def test_Gadino(self):
        ifile = 'Gadino_Min15.dat'
        start,end = '2015-07-02 10:59:59','2017-02-01 00:00:00'
        hydrocodes = ('Gadino_air','Gadino_canopy')
        nulls = (2,),(2,)
        records = (1,list(range(35137,35140+1))+list(range(90047,90058+1)))
        interval = 15
        rowlength = 12
        datapoints = 1+2*len(records[1])
        pointchecks = (
            (90051,(
                '2017-01-24 12:15:00,90051,NULL,5.311333,80.93,275.7236,0,15,0,0,15,Gadino_air',
                '2017-01-24 12:15:00,90051,NULL,15.13467,65.253,271.6607,15,0,0,0,15,Gadino_canopy',
                )),
                )
        self.check_rowcount_rowlength_hydrocode_interval_nulls_records(
            ifile,start,end,rowlength,hydrocodes,records,nulls,interval,datapoints,pointchecks)

    def test_AHSPP(self):
        ifile = 'AHSPP_Min15.dat'
        start,end = '2014-9-30 23:59:59','2014-10-5 00:00:00'
        hydrocodes = ('AHSPP_air','AHSPP_canopy')
        nulls = (2,),(2,)
        records = (1,list(range(12508,12891+1)))
        interval = 15
        rowlength = 12
        datapoints = 1+2*4*24*4
        pointchecks = (
            (12508,(
                '2014-10-01 00:00:00,12508,NULL,15.27073,99.998,362.2337,0,0,15,0,15,AHSPP_air',
                '2014-10-01 00:00:00,12508,NULL,15.56787,99.998,306.1296,0,0,15,0,15,AHSPP_canopy',
                )),
                )
        self.check_rowcount_rowlength_hydrocode_interval_nulls_records(
            ifile,start,end,rowlength,hydrocodes,records,nulls,interval,datapoints,pointchecks)

    def test_AHSGPCH(self):
        ifile = 'AHSGP-CH_Min15.dat'
        start,end = '2014-09-30 23:59:59','2014-10-05 00:00:00'
        hydrocodes = ('AHSGP-CH_air','AHSGP-CH_canopy')
        nulls = (2,),(2,)
        records = (1,list(range(12611,12994+1)))
        interval = 15
        rowlength = 12
        datapoints = 1+2*4*24*4
        pointchecks = (
            (12611,(
                '2014-10-01 00:00:00,12611,NULL,15.27893,99.998,377.8919,0,0,15,0,15,AHSGP-CH_air',
                '2014-10-01 00:00:00,12611,NULL,15.20867,99.998,290.9353,0,0,15,0,15,AHSGP-CH_canopy',
                )),
                )
        self.check_rowcount_rowlength_hydrocode_interval_nulls_records(
            ifile,start,end,rowlength,hydrocodes,records,nulls,interval,datapoints,pointchecks)

    def test_AHSENV(self):
        ifile = 'AHSENV_Min15.dat'
        start,end = '2014-9-30 23:59:59','2014-10-5 00:00:00'
        hydrocodes = ('AHSENV_air','AHSENV_canopy')
        nulls = (2,-3),(2,-3)
        records = (1,list(range(13448,13830+1)))
        interval = 15
        rowlength = 12
        # ./idata/AHSENV_Min15.dat is missing the 2014-10-04 00:00:00 data point!!
        datapoints = 1+2*(4*24*4-1)
        pointchecks = (
            (13448,(
                '2014-10-01 00:00:00,13448,NULL,24.97,49.97,267.8,15,0,0,NULL,15,AHSENV_air',
                '2014-10-01 00:00:00,13448,NULL,23.47,53.01,266.5,15,0,0,NULL,15,AHSENV_canopy',
                )),
                )
        self.check_rowcount_rowlength_hydrocode_interval_nulls_records(
            ifile,start,end,rowlength,hydrocodes,records,nulls,interval,datapoints,pointchecks)

    def test_AHSGPO(self):
        ifile = 'AHSGP-O_Min15.dat'
        start,end = '2014-09-30 23:59:59','2014-10-05 00:00:00'
        hydrocodes = ('AHSGP-O_air','AHSGP-O_canopy')
        nulls = (2,),(2,)
        records = (1,list(range(12602,12985+1)))
        interval = 15