#date sorts studies from orthanc dataset into target study dataset

#takes transferQuery as the list of images that should be available on orthanc


import os
import json
import re
import sys
import datetime
import re

def main(parameterFile):
    fhome=os.path.expanduser('~')
    fsetup=os.path.join(fhome,'.labkey','setup.json')
    with open(fsetup,'r') as f:
        setup=json.load(f)

    sys.path.insert(0,setup['paths']['nixWrapper'])

    import nixWrapper

    nixWrapper.loadLibrary("labkeyInterface")

    import labkeyInterface
    import labkeyDatabaseBrowser
    import labkeyFileBrowser

    fconfig=os.path.join(fhome,'.labkey','network.json')

    net=labkeyInterface.labkeyInterface()
    net.init(fconfig)
    db=labkeyDatabaseBrowser.labkeyDB(net)
    fb=labkeyFileBrowser.labkeyFileBrowser(net)

    with open(parameterFile,'r') as f:
        pars=json.load(f)



    i=0
    #from orthancDatabase/Imaging dataset
    projectOrthanc=pars['Orthanc']['project']
    inputQuery=pars['Orthanc']['queryName']
    inputSchema=pars['Orthanc']['schemaName']
    inputParticipantField=pars['Orthanc']['participantField']

    #to target project dataset
    projectStudy=pars['Database']['project']
    #'iPNUMMretro/Study'
    #for prospective, set
    #projectStudy='IPNUMMprospektiva/Study'
    outputQuery=pars['Database']['queryName']
    outputSchema=pars['Database']['schemaName']
    #select patientId that are contained in the demographics dataset
    transferQuery=pars['Database']['transferQuery']
    dbParticipantField=pars['Database']['participantField']

    missingSchema=pars['Database']['missingImagesSchema']
    missingQuery=pars['Database']['missingImagesQuery']

    #make a list of images from transferQuery
    dsImage=db.selectRows(projectStudy,outputSchema,transferQuery,[])

    for im in dsImage['rows']:
        inputIdFilter={'variable':inputParticipantField,\
                'value':im[dbParticipantField],\
                'oper':'eq'}

        idFilter={'variable':dbParticipantField,\
                'value':im[dbParticipantField],\
                'oper':'eq'}
        #have to convert from datetime to %Y%m%d format
        #dateFilter={'variable':'imageDate','value':im['imageDate'],'oper':'eq'}

        dsOrthanc=db.selectRows(projectOrthanc,inputSchema,inputQuery,[inputIdFilter])
        #what if dsOrthanc['rows'] is empty?
        #this is part of QA and is reported in missingImages Schema/Query

        uploadStatus="FAILED"
        imageDateMismatch=[]
        for im1 in dsOrthanc['rows']:

            date=datetime.datetime.strptime(im1['studyDate'],'%Y/%m/%d %H:%M:%S') 
            #convert date to %Y%m%d notation
            dateYMD=date.strftime('%Y%m%d')
            if dateYMD!=im['imageDate']:
                print('Rejecting mismatch: {}/{}'.format(dateYMD,im['imageDate']))
                imageDateMismatch.append(dateYMD)
                continue
        
            outvar='NONE'
            sd=im1['seriesDescription']
            if sd=='PET WB':
                outvar='PETWB_orthancId'
                print('Found PET: {}'.format(im1['orthancSeries']))
            if sd.find('CT WB')==0:
                if sd.find('fov')<0:
                    outvar='CT_orthancId'
                    print('Found CT: {}'.format(im1['orthancSeries']))

            #skip irrelevant series
            if outvar=='NONE':
                continue

            #figure out which row in output study to update
            filters=[]
            seqNum=im['imagingVisitId']
            seqFilter={'variable':'SequenceNum','value':str(seqNum),'oper':'eq'}
            print('Participant {} Sequence number {}'.\
                    format(im[dbParticipantField],str(seqNum)))
            #ds1 are the matching outputs in target dataset
            ds1=db.selectRows(projectStudy,outputSchema,outputQuery,\
                [idFilter,seqFilter])
    
            if len(ds1['rows'])>1:
                print('ERROR: too many matches for {}/{}'.\
                    format(im[dbParticipantField],seqNum))
                status="MULTIPLE MATCHES"
                continue

            mode='update'
            outRow={}
            if len(ds1['rows'])==0:
                mode='insert'
        
                outRow[dbParticipantField]=im[dbParticipantField]
                outRow['SequenceNum']=seqNum
                outRow['dicomStudy']=im1['dicomStudy']
        
            else:
                outRow=ds1['rows'][0]
        
            outRow[outvar]=im1['orthancSeries']
            outRow['studyDate']=im1['studyDate']
            outRow['imagingVisitId']=im['imagingVisitId']
            outRow['visitCode']='VISIT_'+str(im['imagingVisitId'])

            modifyStatus=db.modifyRows(mode,projectStudy,outputSchema,\
                    outputQuery,[outRow])
            print('{}'.format(modifyStatus))
            uploadStatus="LOADED"
        
        if uploadStatus=="FAILED":
            #standard spiel - find if already present; if so, skip, if not, add
            imFilter={'variable':'imagingVisitId',
                    'value':'{}'.format(im['imagingVisitId']),
                    'oper':'eq'}
            dsMissing=db.selectRows(projectStudy,missingSchema,\
                    missingQuery,[idFilter,imFilter])

            #already recorded
            imageDateMismatch=list(set(imageDateMismatch))
            vals=[dbParticipantField,'imagingVisitId','imageDate']
            mode='insert'
            if len(dsMissing['rows'])>0:
                mode='update'
                orow=dsMissing['rows'][0]
            else:
                orow={v:im[v] for v in vals}
            orow['imageDateMismatch']=','.join(imageDateMismatch)
            orow['failureDescription']='MISSING DICOM'
            db.modifyRows(mode,projectStudy,missingSchema,\
                    missingQuery,[orow])
            
       
    print("Done")

if __name__=='__main__':
    main(sys.argv[1])
