
import urllib.request
import json
import time
import random
import os

def getjson(url):
    ddosAvoidDelay = random.randint(5,55) / 10.0
    print('wait',ddosAvoidDelay,'sec to avoid ddos',end='\r')
    time.sleep(ddosAvoidDelay)
    raw = urllib.request.urlopen(url).read()
    print('fetched',len(raw),'bytes',' '*40, end='\n')
    data = json.loads(raw)
    return data

def savejson(data,filename):
    if os.path.isfile(filename):
        return
    with open(filename,'w') as f:
        json.dump(data,f,indent=4)

def download(url,filename):
    filepath = 'data/'+filename
    if os.path.isfile(filepath):
        print(' '*20,'already downloaded so loading',end='\r')
        dataOnDisk = json.load(open(filepath))
        if dataOnDisk == []:
            dataOnDisk = {}
        return dataOnDisk
    #if not [True for s in ['ADT','MDM','ORU', 'ORM', ] if s in filename]:
    #    return
    return
    if url:
        print(url,'=>',filepath)
        data = {}
        try:
            data = getjson(url)
        except:
            print(url,'fuck it')
        savejson(data,filepath)
        return data

def fetchTriggers():
    triggerLst = download('https://hl7-definition.caristix.com/v2-api/1/HL7v2.5.1/TriggerEvents','triggers.json')
    for trigger in triggerLst:
        triggerDef = download('https://hl7-definition.caristix.com/v2-api/1/HL7v2.5.1/TriggerEvents/'+trigger['id'],'triggers_'+trigger['id']+'.json')
        yield triggerDef

def fetchSegments(segments=[]):
    segmentLst = segments or download('https://hl7-definition.caristix.com/v2-api/1/HL7v2.5.1/Segments', 'segments.json')
    for segment in segmentLst:
        if not segment['id']:
            continue
        segmentDef = download('https://hl7-definition.caristix.com/v2-api/1/HL7v2.5.1/Segments/'+segment['id'], 'segment_'+segment['id']+'.json')
        if segmentDef:
            yield segmentDef

def fetchFields(fields,ks=set()):
    for field in fields:
        if not field['id'] in ks:
            ks.add(field['id'])
            fieldDef = download('https://hl7-definition.caristix.com/v2-api/1/HL7v2.5.1/Fields/'+field['id'],'field_'+field['id']+'.json')
            if fieldDef:
                yield fieldDef

def Tpl(filename, key=None, val=[]):
        try:
            template = json.load(open(filename))
        except:
            template = {}
        if key:
            if not key in template:
                template[key] = []
            if not val in template[key]:
                template[key].append( val )
            with open(filename,'w') as f:
                #f.truncate()
                json.dump(template,f,indent=4)
        return template

def DmpTsv(filename,tpl):
    open(filename,'a+').write('\t'.join(tpl)+'\n')

def MakeTemplate(filename='template.json'):
    template = Tpl(filename)
    '''
    for segmentDef in fetchSegments():
        segmentName = segmentDef['id']
        print(segmentName)
        print(segmentDef['description'])
        template = Tpl(filename, segmentName, [segmentDef['longName']])
        for fieldDef in fetchFields(segmentDef['fields']):
            fieldName = fieldDef['name']
            fieldPos = fieldDef['position']
            print(fieldPos,end='\r')
            template = Tpl(filename, fieldPos, [fieldName])
            for comp in fetchFields(fieldDef['fields']):
                compname = comp['name']
                comppos = comp['position']
                print(comppos,end='\r')
                template = Tpl(filename, comppos, [ fieldName, compname ])
                for sub in fetchFields(comp['fields']):
                    subname = sub['name']
                    subpos = sub['position']
                    print(subpos,end='\r')
                    template = Tpl(filename, subpos, [ fieldName, compname, subname ])
    '''
    if os.path.exists('GRP.tsv'):
        os.remove('GRP.tsv')
    DmpTsv('GRP.tsv',('GRP','HED','SEG','HNT'))
    if os.path.exists('TRG.tsv'):
        os.remove('TRG.tsv')
    DmpTsv('TRG.tsv',('MessageStructureId','MessageType','MessageTrigger','GRP'))
    def groupParse(groupSeg={}):
        groupTpl = {
        'name' : groupSeg['name'],
        'segments' : [{
            'id':segment['segments'][0]['name'] if segment['segments'] else segment['name'],
            'name':segment['name'],
            'sequence':sequence,
            'usage':segment['usage'],
            'repeat':segment['rpt']
            }
            for sequence,segment in enumerate(groupSeg['segments'])
            ]
        }
        for segment in groupSeg['segments']:
            grpName = groupSeg['name']
            hedName = groupSeg['segments'][0]['name']
            segName = segment['segments'][0]['name'] if segment['segments'] else segment['name']
            hntName = segment['name']
            DmpTsv('GRP.tsv',(grpName,hedName,segName,hntName))
            if segment['segments']:
                groupParse(segment)
        Tpl(filename,groupSeg['name'],groupTpl)
        
    for triggerDef in fetchTriggers():
        print(triggerDef['id'])
        triggerName = triggerDef['id'].replace('_','^')
        msgStructId = triggerDef['msgStructId']
        segments = triggerDef['segments']
        DmpTsv('TRG.tsv',(msgStructId,triggerName.split('^')[0],(triggerName.split('^')+[''])[1],triggerName))
        for segment in segments:
            segName = segment['segments'][0]['name'] if segment['segments'] else segment['name']
            #DmpTsv('GRP.tsv',(triggerName,segments[0]['name'],segment['name']))
            DmpTsv('GRP.tsv',(msgStructId,segments[0]['name'],segName,segment['name']))
            if segment['segments']:
                groupParse(segment)
        Tpl(filename, triggerName, {
            'id':triggerName,
            'name':msgStructId,
            'segments':[{
                'id': segment['segments'][0]['name'] if segment['segments'] else segment['name'],
                'name':segment['name'],
                'sequence':sequence,
                'usage':segment['usage'],
                'repeat':segment['rpt']
            }for sequence,segment in enumerate(segments)
            ]
        })
            
            
    print('done', filename)

MakeTemplate('type.json')

