import numpy
import os
import json
import time
import cModel
import importlib
import runSolver
import numpy.linalg
#Zalaufaj metodo solve_matrics namest IVP, method seperately.  Preverjas razlicne metode resevanja enega modela, pol ko bos pa naredi kopijo novega modela glede na članek kotinin
importlib.reload(cModel)
importlib.reload(runSolver)

def getModel(solution, modelName):
    Q = solution[modelName]
    model = cModel.model()
    setupFile = Q['setup']
    modelFile = Q['model']
    parameterFile = Q['parameters']
    print('modelFile: {} {}'.format(modelFile, os.path.isfile(modelFile)))
    print('parameterFile: {} {}'.format(parameterFile, os.path.isfile(parameterFile)))
    model.parse(modelFile, parameterFile)
    return model
def getSum(data,modelName):
    
    model=getModel(data,modelName)
    Q=data[modelName]['solution']
    lut=Q['lut']
    total=Q['sol'][-1,lut['total']]
    #print(total)
    fQ={}
    for x in lut:
        if x=='total':
            continue
        j=lut[x]
        try:
            v=model.get(model.mod['volumes'][x])['value']
            fQ[x]=Q['sol'][-1,j]*v/total
        except KeyError:
            #print('{} {}'.format(x,x in model.mod['scaled']))
            fQ[x]=Q['sol'][-1,j]
    print(sum(list(fQ.values())))
    print(sorted(fQ.items(), key=lambda item:item[1]))

def mergeSolutions(seq):
    out={}
    #each element in sequence should have this components
    for v in ['t','sol','se','qt','sOut']:
        out[v]=numpy.concatenate([x[v] for x in seq])
    #copy last for settings
    for v in ['lut','lutSE','setup','model','parameters','qt','sOut']:
        out[v]=seq[-1][v]
    return out 

def updateSetup(job):
    setupFileSrc = job['setupFile']
    setupFile = os.path.join(job['jobDir'], 'setupInput.json')
    with open(setupFileSrc, 'r') as f:
        setup = json.load(f)
    try:
        setup.update(job['setupUpdates'])
    except KeyError:
        pass
    with open(setupFile, 'w+') as f:
        f.write(json.dumps(setup))
    return setupFile

fh = os.path.expanduser('~')

# Create job configurations
job_configs = {
    'cDiazepam': {
        'jobDir': os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'cDiazepam_Matrix'),
        'modelFile': os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'models', 'cDiazepam.json'),
        'parameterFile': os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'models', 'cDiazepam_parameters2.json'),
        'setupFile': os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'setup', 'setupMinute.json'),
        'setupUpdates': {'mode': 'solveMatrix', 'method': 'separately'}, #Mode:IVP mode:LSOD
        'srcDir': 'NONE',
        'doCalculate': True
    },
    'cDiazepam1': {
        'jobDir': os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'cDiazepam1_Matrix'),
        'modelFile': os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'models', 'cDiazepam.json'),
        'parameterFile': os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'models', 'cDiazepam_parameters2.json'),
        'setupFile': os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'setup', 'setupHours.json'),
        'setupUpdates': {'mode': 'solveMatrix', 'method': 'separately'}, #Mode:IVP mode:LSOD
        'srcDir': 'NONE',
        'doCalculate': True
    },
    'cDiazepamF': {
        'jobDir': os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'cDiazepamF_Matrix'),
        'modelFile': os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'models', 'cDiazepam.json'),
        'parameterFile': os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'models', 'cDiazepam_parameters1.json'),
        'setupFile': os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'setup', 'setupMinute.json'),
        'setupUpdates': {'mode': 'solveMatrix', 'method': 'separately'}, 
        'srcDir': 'NONE',
        'doCalculate': True
    },
    'cDiazepamB': {
        'jobDir': os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'cDiazepamB_Matrix'),
        'modelFile': os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'models', 'cDiazepam.json'),
        'parameterFile': os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'models', 'cDiazepam_parameters1.json'),
        'setupFile': os.path.join(fh, 'Documents', 'Sola', 'IJS', 'PBPK_public', 'setup', 'setupHours.json'),
        'setupUpdates': {'mode': 'solveMatrix', 'method': 'separately'}, 
        'srcDir': 'NONE',
        'doCalculate': True
    }
}

# Execute jobs
for job_name, job in job_configs.items():
    if not job['doCalculate']:
        continue

    if not os.path.isdir(job['jobDir']):
        os.mkdir(job['jobDir'])
        
    # Adjust local setup file with ad-hoc modifications
    setupFile = updateSetup(job)
#   t0,y0,S1,lut,lutSE=runSolver.getStartPoint(setupFile)               #Pridobivanje začetnih točk
    runSolver.main([setupFile, job['modelFile'], job['parameterFile']], job['jobDir'], job['srcDir'])
#(t0,y0,S1,lut,lutSE=runSolver.getStartPoint(setup)      )            #Pridobivanje začetnih točk
#Zalaufaj metodo solve_matrics namest IVP, method seperately.  Preverjas razlicne metode resevanja enega modela, pol ko bos pa naredi kopijo novega modela glede na članek kotinin

