import os
import sys
import config
import analysis
import json
import SimpleITK

def connectDB(server):
   sPath=os.path.join(os.path.expanduser('~'),'.labkey','setup.json')
   with open(sPath,'r') as f:
      setup=json.load(f)

   sys.path.append(setup['paths']['nixWrapper'])
   import nixWrapper
   nixWrapper.loadLibrary('labkeyInterface')
   import labkeyInterface


   net=labkeyInterface.labkeyInterface()
   fconfig=os.path.join(os.path.expanduser('~'),'.labkey',server)
   net.init(fconfig)
   net.getCSRF()
   import labkeyDatabaseBrowser
   import labkeyFileBrowser
   return labkeyDatabaseBrowser.labkeyDB(net),labkeyFileBrowser.labkeyFileBrowser(net)

def getDataset(db,setup,datasetName,qfilter=[]):
    ds=db.selectRows(setup['project'],setup['schemaName'],\
      setup[datasetName],qfilter)
    try:
        rows=ds['rows']
    except KeyError:
        rows=[]
    return rows

def updateDataset(db,setup,datasetName,mode,rows):
   db.modifyRows(mode,setup['project'],setup['schemaName'],\
      setup[datasetName],rows)
   
def getPatients(db,setup,qfilter=[]):
   return getDataset(db,setup,'queryName',qfilter)

def getSegmentation(db,setup,qfilter=[]):
   return getDataset(db,setup,'segmentationQueryName',qfilter)

def getSummary(db,setup,qfilter=[]):
   return getDataset(db,setup,'summaryQueryName',qfilter)

def updatePatients(db,setup,mode,rows):
   updateDataset(db,setup,'queryName',mode,rows)

def updateSegmentation(db,setup,mode,rows):
   updateDataset(db,setup,'segmentationQueryName',mode,rows)

def updateSummary(db,setup,mode,rows):
   updateDataset(db,setup,'summaryQueryName',mode,rows)

def downloadNode(fb,fileName,rPath,lPath):
    rPath1=rPath+'/'+fileName
    available=fb.entryExists(rPath1)
    if not available:
        print('Missing {}'.format(fileName))
        return
    lPath1=os.path.join(lPath,fileName)
    if os.path.isfile(lPath1):
        return
    print('Loading {}'.format(fileName))
    fb.readFileToFile(rPath1,lPath1)

def downloadFiles(fb,r,setup):
    
    #CT
    fileName=config.getNodeName(r,setup,'CT')+'.nrrd'
    copyFromServer(fb,r,setup,[fileName])
    
    for i in range(20):
        fileName=config.getNodeName(r,setup,'NM',i)+'.nrrd'
        copyFromServer(fb,r,setup,[fileName])

    
    fileName=config.getNodeName(r,setup,'Dummy')+'.mcsv'
    copyFromServer(fb,r,setup,[fileName])
    
def downloadPatientFiles(db,fb,setup,qfilter=[]):
    rows=getPatients(db,setup,qfilter)
    for r in rows:
        #download
        downloadFiles(fb,r,setup)

def uploadCenters(fb,r,setup):
   names=config.printRowCenterNames(r,setup)
   copyToServer(fb,r,setup,names)

def downloadCenters(fb,r,setup):
   names=config.printRowCenterNames(r,setup)
   copyFromServer(fb,r,setup,names)

def uploadFitParFinal(fb,r,setup,mode):
   names=config.printFitParFinalRowNames(r,setup,mode)
   #copy files to server
   copyToServer(fb,r,setup,names)

def downloadFitParFinal(fb,r,setup,mode):
   names=config.printFitParFinalRowNames(r,setup,mode)
   #copy files to server
   copyFromServer(fb,r,setup,names)

def uploadPixelFitParFinal(fb,r,xsetup,m='IVF'):
   sigma2=xsetup['sigma2']
   #get nc
   nc=segmentation.getNC(r,xsetup)
   
   for s2 in sigma2:
      names=config.printPixelFitParFinalRowNames(r,xsetup,nc,s2,m)
      copyToServer(fb,r,setup,names)


def copyToServer(fb,r,setup,names):
   remoteDir=fb.buildPathURL(setup['project'],config.getPathList(r,setup))
   for n in names:
      localPath=getLocalPath(r,setup,n)
      remotePath='{}/{}'.format(remoteDir,n)
      fb.writeFileToFile(localPath,remotePath)

def copyFromServer(fb,r,setup,names):
   try:
      forceReload=setup['forceReload']
   except KeyError:
      forceReload=False

   getLocalDir(r,setup,createIfMissing=True)
   remoteDir=fb.buildPathURL(setup['project'],config.getPathList(r,setup))
   for n in names:
      localPath=getLocalPath(r,setup,n)
      if os.path.isfile(localPath) and not forceReload:
         continue
      remotePath='/'.join([remoteDir,n])
      fb.readFileToFile(remotePath,localPath)

def getLocalDir(r,setup,createIfMissing=False):
   localDir=os.path.join(config.getTempDir(setup),config.getCode(r,setup))
   if createIfMissing:
      if not os.path.isdir(localDir):
         os.makedirs(localDir)
   return localDir

def getLocalPath(r,setup,name):
   tempDir=config.getTempDir(setup)
   code=config.getCode(r,setup)
   fileName=name[name.rfind('/')+1:]
   return os.path.join(tempDir,code,fileName)

def getURL(fb,r,setup,name):
   remoteDir=fb.buildPathURL(setup['project'],config.getPathList(r,setup))
   return '/'.join([remoteDir,name])
 
def getPatientNIM(fb,r,setup):
    fileName=config.getNodeName(r,setup,'NM',19)+'.nrrd'
    f=getLocalPath(r,setup,fileName)
    if not os.path.isfile(f):
#download from server
       copyFromServer(fb,r,setup,[fileName])

    im=SimpleITK.ReadImage(f)
    nim=SimpleITK.GetArrayFromImage(im)
    return nim

def updateStatus(db,r,setup,var,status=True):
#update status of var to status
   fVars=['patientCode','visitCode']
   qFilter=[{'variable':x,'value':'{}'.format(r[x]),'oper':'eq'} for x in fVars]
   ds=db.selectRows(setup['project'],'study','processingStatus',qFilter)
   try:
      rows=ds['rows']
   except KeyError:
      #no rows returned, possibly the dataset does not exist
      return        
   mode='update'
   try:
      entry=rows[0]
   except IndexError:
      fVars.extend([config.getPatientField(setup), "SequenceNum"])
      entry={x:r[x] for x in fVars}
      mode='insert'
   entry[var]=status

   db.modifyRows(mode,setup['project'],'study','processingStatus',[entry])