import string,re,sys,itertools
'''
cut pasted from hss.py cookbook
'''
class Sql(object):
    @staticmethod
    def compile(dbname,querytxt):
        conn = sqlite3.connect(dbname)
        try:
            cur = conn.cursor()
            cur.executescript(querytxt)
            conn.commit()
        except Exception as e:
            logging.error(e)
        return conn

    def __init__(self):
        self.conn = False

    def _connect(self):
        if not self.conn:
            self.conn = sqlite3.connect(':memory:',
                                        check_same_thread=False,
                                        isolation_level=None)
        return self

    def compile(self,querytxt):
        self._connect()
        try:
            cur = self.conn.cursor()
            cur.executescript(querytxt)
            self.conn.commit()
        except Exception as e:
            logging.error(e)
            logging.info(e)
        return self

    def attach(self,dbfile,dbname):
        if os.path.exists(dbfile+'-journal'):
            os.remove(dbfile+'-journal')
        self._connect()
        for db in self.query('PRAGMA database_list;'):
            if db['name'] == dbname:
                return
        self.conn.cursor().execute("ATTACH DATABASE '%(dbfile)s' AS %(dbname)s;" % {'dbfile':dbfile,'dbname':dbname})
        self.conn.commit()
        return self

    def query(self,querytxt,*args):
        self._connect()
        result=[]
        try:
            cur = self.conn.cursor()
            cur.execute(querytxt,args)
            col = [ attr[0] for attr in cur.description ] if cur.description else []
            for row in cur.fetchall():
                if cur.description:
                    yield dict(zip(col,row))
                else:
                    yield list(row)
        except Exception as e:
            logging.error(e)

    def update(self,querytxt,*args):
        self._connect()
        try:
            cur = self.conn.cursor()
            cur.execute(querytxt,args)
            self.conn.commit()
            return cur.lastrowid
        except Exception as e:
            if not 'UNIQUE' in str(e):
                logging.error(e)

    def bulk(self,querytxt,blk=[]):
        self._connect()
        try:
            cur = self.conn.cursor()
            cur.execute('BEGIN TRANSACTION;')
            cur.executemany(querytxt,blk)
            cur.execute('COMMIT;')
            self.conn.commit()
        except Exception as e:
            if not 'UNIQUE' in str(e):
                logging.error(e)


'''
the thing
'''
def floodTheShit(src):
    #from highSpeedSandwitch.hss import Sql
    sql = Sql()
    sql.attach(src,'hl7')
    from hl7 import SqlHl7
    _, sqlload = SqlHl7(Sql())

    def getTrg(src,seq):
        for tp in sql.query('select VAL from hl7.HL7 where SRC = ? and SEQ = ? and ROW = 0 and COL = 8 and COM = 0',src,seq):
            for tr in sql.query('select VAL from hl7.HL7 where SRC = ? and SEQ = ? and ROW = 0 and COL = 8 and COM = 1',src,seq):
                for trg in sql.query('select MessageStructureId, GRP from hl7.TRG where MessageType = ? and MessageTrigger = ?',tp['VAL'],tr['VAL']):
                    return trg['MessageStructureId']

    def getGrp(seg,grpT=[],hnt=[]):
        for i in range(len(grpT)):
            for r in sql.query('select HNT,SEG,HED from hl7.GRP WHERE SEG!=HNT and GRP = ?',grpT[i]):
                grp = r['HNT']
                hed = r['HED']
                grpTT = [grp] + grpT[i:]
                if not grp in hnt:
                    hnt.append(grp)
                    for chld in getGrp(seg, grpTT, hnt):
                        yield chld
                if r['SEG'] == seg:
                    yield grpTT
        yield grpT

    def Frst(a=[],default=None):
        for e in a:
            return e
        return default

    def PerCol(it):
        SEG = 'MSH'
        for VAL,_,_,COL,COM,SUB,REP,_ in it:
            if COL == 0:
                SEG = VAL
                yield 'SEG', VAL
            key = ("%s_%d_%d_%d__%d" % (SEG,COL,COM,SUB,REP)).replace('__0','')
            yield key , VAL

    def inCtx(src,seq, it):
        #st = getTrg(src,seq)
        dick = {}
        #grpT = [st]
        for row,itt in itertools.groupby(it, lambda t : t[2]):
            nudick = dict(PerCol(itt))
            #attempt to make thing well
            for key in set(dick):
                if key.startswith(nudick['SEG']):
                    dick.pop(key,None)
            dick.update(nudick)
            #grpT = Frst( getGrp(dick['SEG'] , []+grpT ) , []+grpT)
            #dick['GRP'] = grpT[0]
            print(src,seq,row,dick['SEG']) #,grpT[0])
            yield row,dick['SEG'],dick

    for msh,it in itertools.groupby(sqlload(), lambda t : (t[7],t[1]) ):
        src,seq = msh
        yield src,seq, inCtx(src,seq, it)



templateCatalog = dict({
'Patient': {
    'MSH' : ['''
            var patient = GetPatient("$PID_3_0_0");
            if (patient == null) { Assert.Inconclusive("patient not found"); }

            //Assert.AreEqual( null , patient.ModificationDate );
            //Assert.AreEqual( null , patient.ModificationUser );

            Assert.AreEqual( null , patient.RAMQ );
            Assert.AreEqual( null , patient.DateOfDeath );

            Assert.AreEqual( "$PID_5_1_0" , patient.FirstName );
            Assert.AreEqual( "$PID_5_2_0" , patient.MiddleName );
            Assert.AreEqual( "$PID_5_0_0" , patient.LastName );
            Assert.AreEqual( "$PID_8_0_0" , patient.Gender );

            Assert.AreEqual( new DateTime("$PID_7_0_0") , patient.Birthday );
            //Assert.AreEqual( new DateTime("$MSH_6_0_0") , patient.DateLastMessage );

            //Assert.AreEqual( "rule specific" , patient.PrimaryExternalCode );
''',],
},
'PatientExternalCode' : {
    'MSH' : ['''
            var patient = GetPatient("$PID_3_0_0");
            if (patient == null) { Assert.Inconclusive("patient not found"); }
            var patientExternalCodeCnt = 0;
'''],
    'PID' : ['''
            {
                var patientExternalCode = patient.PatientExternalCodes.ElementAt(patientExternalCodeCnt++);

                //Assert.AreEqual( null , patientExternalCode.ModificationUser );
                //Assert.AreEqual( null , patientExternalCode.ModificationDate );

                // PID 3.x.y Patient Identifier List
                Assert.AreEqual( "$PID_3_0_0" , patientExternalCode.ExternalCode );
                //Assert.AreEqual( "$PID_3_3_0" , patientExternalCode.AssigningAuthority );
                //Assert.AreEqual( "$PID_3_4_0" , patientExternalCode.IdentifierCode );
                //Assert.AreEqual( "$PID_3_5_0" , patientExternalCode.Facility );
                Assert.AreEqual( "ALGI01CH" , patientExternalCode.AssigningAuthority  , "constant chicoutimi");
                Assert.AreEqual( "PRI" , patientExternalCode.IdentifierCode , "constant chicoutimi" );
                Assert.AreEqual( "51218394" , patientExternalCode.Facility  , "constant chicoutimi");
            }
''','''
            {
                if (patient.PatientExternalCodes.Count() <= patientExternalCodeCnt)
                {
                    Assert.Inconclusive("alternate id not mapped");
                }
                var patientExternalCode = patient.PatientExternalCodes.ElementAt(patientExternalCodeCnt++);

                //Assert.AreEqual( null , patientExternalCode.ModificationUser );
                //Assert.AreEqual( null , patientExternalCode.ModificationDate );

                // PID 4.x.y Alternate Patient Identifier
                Assert.AreEqual( "$PID_4_0_0" , patientExternalCode.ExternalCode );
                //Assert.AreEqual( "$PID_4_3_0" , patientExternalCode.AssigningAuthority );
                //Assert.AreEqual( "$PID_4_4_0" , patientExternalCode.IdentifierCode );
                //Assert.AreEqual( "$PID_4_5_0" , patientExternalCode.Facility );
            }
''']+['''
            {
                if (patient.PatientExternalCodes.Count() <= patientExternalCodeCnt)
                {
                    Assert.Inconclusive("repeated alternate id not mapped");
                }
                var patientExternalCode = patient.PatientExternalCodes.ElementAt(patientExternalCodeCnt++);

                //Assert.AreEqual( null , patientExternalCode.ModificationUser );
                //Assert.AreEqual( null , patientExternalCode.ModificationDate );

                // PID 4.x.y Alternate Patient Identifier Repetition
                Assert.AreEqual( "$PID_4_0_0__$REP" , patientExternalCode.ExternalCode );
                //Assert.AreEqual( "$PID_4_3_0__$REP" , patientExternalCode.AssigningAuthority );
                //Assert.AreEqual( "$PID_4_4_0__$REP" , patientExternalCode.IdentifierCode );
                //Assert.AreEqual( "$PID_4_5_0__$REP" , patientExternalCode.Facility );
            }
'''.replace('$REP', str(i)) for i in range(4) ],
},
'PatientAddresses' : {
    'MSH' : ['''
            var patient = GetPatient("$PID_3_0_0");
            if (patient == null) { Assert.Inconclusive("patient not found"); }
            var patientAddressCnt = 0;
'''],
    'PID' : ['''
            {
                if (patient.PatientAddresses.Count() <= patientAddressCnt)
                {
                    Assert.Inconclusive("not mapped");
                }
                var patientAddress = patient.PatientAddresses.ElementAt(patientAddressCnt++);

                //Assert.AreEqual( null , patientAddress.ModificationUser );
                //Assert.AreEqual( null , patientAddress.ModificationDate );

                Assert.AreEqual( new DateTime("$MSH_6_0_0") , patientAddress.DateOfMessage );
                Assert.AreEqual( "" , patientAddress.AddressType );
                Assert.AreEqual( "" , patientAddress.Street1 );
                Assert.AreEqual( "" , patientAddress.Street2 );
                Assert.AreEqual( "" , patientAddress.City );
                Assert.AreEqual( "" , patientAddress.Province );
                Assert.AreEqual( "" , patientAddress.PostalCode );
                Assert.AreEqual( "" , patientAddress.CountryCode );
                Assert.AreEqual( "" , patientAddress.PatientHospitalizationExternalCode );
            }
'''],
},
'PatientHospitalizations' : {
    'MSH' : ['''
            var patient = GetPatient("$PID_3_0_0");
            if (patient == null) { Assert.Inconclusive("patient not found"); }
            var patientHospitalizationCnt = 0;
'''],
    'PV1' : ['''
                if (patient.PatientHospitalizations.Count() <= patientHospitalizationCnt)
                {
                    Assert.Inconclusive("not mapped");
                }
                var patientHospitalization = patient.PatientHospitalizations.ElementAt(patientHospitalizationCnt++);
                var eventDate = new DateTime("$EVN_6_0_0");

                //Assert.AreEqual( null , patientHospitalization.ModificationUser );
                //Assert.AreEqual( null , patientHospitalization.ModificationDate );

                //Assert.AreEqual( eventDate , patientHospitalization.End );
                //Assert.AreEqual( eventDate , patientHospitalization.Start );
                Assert.AreEqual( "$PV1_2_0_0" , patientHospitalization.PatientClass );
                Assert.AreEqual( "$PV1_19_0_0" , patientHospitalization.ExternalCode );
                //Assert.AreEqual( new DateTime("$MSH_6_0_0") , patientHospitalization.DateLastMessage );

                var patientHospitalizationBedCnt = 0;
                var patientHospitalizationTransferCnt = 0;
                var patientHospitalizationInfectiologistCnt = 0;
                var patientHospitalizationReasonOfAdmissionCnt = 0;
                var patientHospitalizationPhysicianCnt = 0;
                var patientHospitalizationScreeningQuestionCnt = 0;
                var patientHospitalizationTriageCnt = 0;
                var patientHospitalizationPhysicianHistoryCnt = 0;
''','''
                {
                        var patientHospitalizationReasonOfAdmission = patientHospitalization.PatientHospitalizationReasonOfAdmissions.ElementAt(patientHospitalizationReasonOfAdmissionCnt++);

                        //Assert.AreEqual( null , patientHospitalizationReasonOfAdmission.ModificationDate );
                        //Assert.AreEqual( null , patientHospitalizationReasonOfAdmission.ModificationUser );

                        Assert.AreEqual( "" , patientHospitalizationReasonOfAdmission.CodingSystem );
                        Assert.AreEqual( "" , patientHospitalizationReasonOfAdmission.ReasonOfAdmissionCode );
                        Assert.AreEqual( "" , patientHospitalizationReasonOfAdmission.ReasonOfAdmission );
                        //Assert.AreEqual( patientHospitalization.DateLastMessage , patientHospitalizationReasonOfAdmission.DateOfMessage );
                        //Assert.AreEqual( true , patientHospitalizationReasonOfAdmission.IsEnabled );
                }
''','''
                {
                        var patientHospitalizationPhysician = patientHospitalization.PatientHospitalizationPhysicians.ElementAt(patientHospitalizationPhysicianCnt++);

                        //Assert.AreEqual( null , patientHospitalizationPhysician.ModificationDate );
                        //Assert.AreEqual( null , patientHospitalizationPhysician.ModificationUser );

                        //Assert.AreEqual( true , patientHospitalizationPhysician.IsEnabled );
                        Assert.AreEqual( null , patientHospitalizationPhysician.Physician.PhoneNumber );
                        Assert.AreEqual( null , patientHospitalizationPhysician.Physician.PagerNumber );
                        Assert.AreEqual( null , patientHospitalizationPhysician.Physician.Comment );

                        //Assert.AreEqual( patientHospitalization.DateLastMessage , patientHospitalizationPhysician.DateOfMessage );
                        //Assert.AreEqual( eventDate , patientHospitalizationPhysician.Date );
                        //Assert.AreEqual( patientHospitalization.DateLastMessage , patientHospitalizationPhysician.Date, "CUSM" );
                    
                        Assert.AreEqual( "$PV1_7_2_0" , patientHospitalizationPhysician.Physician.FirstName );
                        Assert.AreEqual( "$PV1_7_3_0" , patientHospitalizationPhysician.Physician.MiddleName );
                        Assert.AreEqual( "$PV1_7_1_0" , patientHospitalizationPhysician.Physician.LastName );
                        //Assert.AreEqual( "$PV1_7_0_0" , patientHospitalizationPhysician.Physician.ExternalCode );
                }
''','''
                {
                    if (patientHospitalization.PatientHospitalizationBeds.Count() <= patientHospitalizationBedCnt)
                    {
                        Assert.Inconclusive("bed not mapped");
                    }
                    var patientHospitalizationBed = patientHospitalization.PatientHospitalizationBeds.ElementAt(patientHospitalizationBedCnt++);

                    //Assert.AreEqual( null , patientHospitalizationBed.ModificationDate );
                    //Assert.AreEqual( null , patientHospitalizationBed.ModificationUser );

                    //Assert.AreEqual( patientHospitalization.End , patientHospitalizationBed.End );
                    //Assert.AreEqual( eventDate , patientHospitalizationBed.Start );
                    //Assert.AreEqual( patientHospitalization.DateLastMessage , patientHospitalizationBed.DateLastMessage );
                    // chicoutimi special edition
                    Assert.AreEqual( "$PV1_3_2_0" ?? patientHospitalizationBed.Bed.Room.RoomCode , patientHospitalizationBed.Bed.BedCode );
                    Assert.AreEqual( "$PV1_3_1_0" ?? patientHospitalizationBed.HospitalUnit.Code, patientHospitalizationBed.Bed.Room.RoomCode );
                    Assert.AreEqual( "$PV1_3_0_0" ?? patientHospitalizationBed.HospitalUnit.Hospital.Code, patientHospitalizationBed.HospitalUnit.Code );
                    Assert.AreEqual( "$PV1_3_3_0" , patientHospitalizationBed.HospitalUnit.Hospital.Code );
                }
''','''
                {
                        var patientHospitalizationTransfer = patientHospitalization.PatientHospitalizationTransfers.ElementAt(patientHospitalizationTransferCnt++);

                        //Assert.AreEqual( null , patientHospitalizationTransfer.ModificationUser );
                        //Assert.AreEqual( null , patientHospitalizationTransfer.ModificationDate );

                        Assert.AreEqual( eventDate , patientHospitalizationTransfer.ArrivalDate );
                        Assert.AreEqual( "" , patientHospitalizationTransfer.ReasonOfAdmission );
                        Assert.AreEqual( "" , patientHospitalizationTransfer.RelevantAntecedents );
                        Assert.AreEqual( "" , patientHospitalizationTransfer.OriginalHospital );
                        Assert.AreEqual( "" , patientHospitalizationTransfer.Specifications );
                        Assert.AreEqual( null , patientHospitalizationTransfer.ReanimationAllowed );
                        Assert.AreEqual( null , patientHospitalizationTransfer.IntubationAllowed );
                        Assert.AreEqual( null , patientHospitalizationTransfer.TransferStatusTypeId );
                }
''','''
                {
                        var patientHospitalizationInfectiologist = patientHospitalization.PatientHospitalizationInfectiologists.ElementAt(patientHospitalizationInfectiologistCnt++);

                        //Assert.AreEqual( null , patientHospitalizationInfectiologist.ModificationDate );
                        //Assert.AreEqual( null , patientHospitalizationInfectiologist.ModificationUser );

                        //Assert.AreEqual( eventDate , patientHospitalizationInfectiologist.Start );
                        //Assert.AreEqual( null , patientHospitalizationInfectiologist.End );
                }
''','''
                {
                        var patientHospitalizationScreeningQuestion = patientHospitalization.PatientHospitalizationScreeningQuestions.ElementAt(patientHospitalizationScreeningQuestionCnt++);

                        //Assert.AreEqual( null , patientHospitalizationScreeningQuestion.ModificationDate );
                        //Assert.AreEqual( null , patientHospitalizationScreeningQuestion.ModificationUser );

                        Assert.AreEqual( "" , patientHospitalizationScreeningQuestion.QuestionId );
                        Assert.AreEqual( "" , patientHospitalizationScreeningQuestion.QuestionText );
                        Assert.AreEqual( "" , patientHospitalizationScreeningQuestion.Answer );
                        //Assert.AreEqual( patientHospitalization.DateLastMessage , patientHospitalizationScreeningQuestion.DateOfMessage );
                        //Assert.AreEqual( eventDate , patientHospitalizationScreeningQuestion.EnabledFrom );
                        Assert.AreEqual( null , patientHospitalizationScreeningQuestion.EnabledTo );
                        Assert.AreEqual( true , patientHospitalizationScreeningQuestion.IsEnabled );
                }
''','''
                {
                        var patientHospitalizationTriage = patientHospitalization.PatientHospitalizationTriages.ElementAt(patientHospitalizationTriageCnt++);

                        //Assert.AreEqual( null , patientHospitalizationTriage.ModificationUser );
                        //Assert.AreEqual( null , patientHospitalizationTriage.ModificationDate );

                        Assert.AreEqual( eventDate , patientHospitalizationTriage.TriageDate );
                        Assert.AreEqual( "" , patientHospitalizationTriage.TriageLevel );
                        //Assert.AreEqual( patientHospitalization.DateLastMessage , patientHospitalizationTriage.DateOfMessage );
                }
''','''
                {
                        var patientHospitalizationPhysicianHistory = patientHospitalization.PatientHospitalizationPhysicianHistories.ElementAt(patientHospitalizationPhysicianHistoryCnt++);

                        //Assert.AreEqual( null , patientHospitalizationPhysicianHistory.ModificationUser );
                        //Assert.AreEqual( null , patientHospitalizationPhysicianHistory.ModificationDate );

                        //Assert.AreEqual( patientHospitalization.DateLastMessage , patientHospitalizationPhysicianHistory.DateOfMessage );
                        Assert.AreEqual( "" , patientHospitalizationPhysicianHistory.PhysicianRoleKey );
                        Assert.AreEqual( true , patientHospitalizationPhysicianHistory.IsEnabled );
                        Assert.AreEqual( "" , patientHospitalizationPhysicianHistory.ExternalCode );
                        Assert.AreEqual( "" , patientHospitalizationPhysicianHistory.FirstName );
                        Assert.AreEqual( "" , patientHospitalizationPhysicianHistory.MiddleName );
                        Assert.AreEqual( "" , patientHospitalizationPhysicianHistory.LastName );
                }
'''],
},
'PatientLabOrders' : {
    'MSH' : ['''
            var patient = GetPatient("$PID_3_0_0");
            if (patient == null) { Assert.Inconclusive("patient not found"); }
            var patientLabOrderCnt = 0;

            var patientLabResultCnt = 0;
            var patientLabOrderNoteCnt = 0;
'''],
    'OBR' : ['''
                if (patient.PatientLabOrders.Count() <= patientLabOrderCnt)
                {
                    Assert.Inconclusive("not mapped");
                }

                var patientLabOrder = patient.PatientLabOrders.ElementAt(patientLabOrderCnt++);

                //Assert.AreEqual( null , patientLabOrder.ModificationDate );
                //Assert.AreEqual( null , patientLabOrder.ModificationUser );
                Assert.AreEqual( null , patientLabOrder.IsVisible );

                Assert.AreEqual( true , patientLabOrder.IsEnabled );
                //Assert.AreEqual( new DateTime("$OBR_7_0_0") , patientLabOrder.Date );
                //Assert.AreEqual( new DateTime("$MSH_6_0_0") , patientLabOrder.DateOfMessage );

                Assert.AreEqual( "" , patientLabOrder.ExternalCode );
                //Assert.AreEqual( "$OBR_4_0_0" , patientLabOrder.GroupOrderNumber );
                //Assert.AreEqual( "$OBR_3_0_0".Split(':')[0] , patientLabOrder.GroupOrderNumber , "chicoutimi" );
                Assert.AreEqual( "$OBR_4_1_0" , patientLabOrder.Name );
                Assert.AreEqual( "$OBR_25_0_0" , patientLabOrder.State );
                //Assert.AreEqual( "$OBR_11_0_0" , patientLabOrder.LisOrderType );
'''],
},
'PatientSerumLevels' : {
    'MSH' : ['''
            var patient = GetPatient("$PID_3_0_0");
            if (patient == null) { Assert.Inconclusive("patient not found"); }
            var patientSerumLevelCnt = 0;
    '''],
    'OBX' : ['''
                if (patient.PatientSerumLevels.Count() <= patientSerumLevelCnt)
                {
                    Assert.Inconclusive("not mapped");
                }
                var patientSerumLevel = patient.PatientSerumLevels.ElementAt(patientSerumLevelCnt++);

                //Assert.AreEqual( null , patientSerumLevel.ModificationDate );
                //Assert.AreEqual( null , patientSerumLevel.ModificationUser );

                //Assert.AreEqual( "$OBX_5_0_0" , patientSerumLevel.Value );
                Assert.AreEqual( "$OBX_5_0_0" , patientSerumLevel.ValueStr );
                Assert.AreEqual( "$OBX_3_1_0" , patientSerumLevel.Name );
                Assert.AreEqual( "$OBX_11_0_0" , patientSerumLevel.State );
                //Assert.AreEqual( "$NTE_3_0_0" , patientSerumLevel.Notes );
                Assert.AreEqual( "$OBX_7_0_0" , patientSerumLevel.ReferenceRange );
                Assert.AreEqual( "$OBX_6_0_0" , patientSerumLevel.Unit );
                //Assert.AreEqual( "$OBX_11_0_0" , patientSerumLevel.AbnormalFlag );

                //Assert.AreEqual( new DateTime("$OBX_14_0_0") , patientSerumLevel.Date );
                //Assert.AreEqual( patientLabOrder.DateOfMessage , patientSerumLevel.LastMessageDate );
                Assert.AreEqual( null , patientSerumLevel.EnabledTo );
                Assert.AreEqual( null , patientSerumLevel.EnabledFrom );

                Assert.AreEqual( true , patientSerumLevel.IsEnabled );
                Assert.AreEqual( null , patientSerumLevel.IsManualEntry );'''],
},
'PatientLabResults' : {
    'MSH' : ['''
            var patient = GetPatient("$PID_3_0_0");
            if (patient == null) { Assert.Inconclusive("patient not found"); }
            var patientLabResultCnt = 0;
    '''],
    'OBX' : ['''
                if (patient.PatientLabResults.Count() <= patientLabResultCnt)
                {
                    Assert.Inconclusive("not mapped");
                }
                var patientLabResult = patient.PatientLabResults.ElementAt(patientLabResultCnt++);

                //Assert.AreEqual( null , patientLabResult.ModificationDate );
                //Assert.AreEqual( null , patientLabResult.ModificationUser );

                Assert.AreEqual( null , patientLabResult.IsManualEntry );
                Assert.AreEqual( true , patientLabResult.IsEnabled );
                //Assert.AreEqual( new DateTime("$OBX_14_0_0") , patientLabResult.Date );
                Assert.AreNotEqual( null , patientLabResult.EnabledFrom );
                Assert.AreEqual( null , patientLabResult.EnabledTo );

                Assert.AreEqual( $OBX_1_0_0 , patientLabResult.Index );
                Assert.AreEqual( "$OBX_3_1_0" , patientLabResult.Name );
                Assert.AreEqual( "$OBX_5_0_0" , patientLabResult.ValueStr );
                //Assert.AreEqual( "$OBX_5_0_0" , patientLabResult.Value );
                Assert.AreEqual( "$OBX_11_0_0" , patientLabResult.State );
                Assert.AreEqual( "$NTE_3_0_0" , patientLabResult.Notes );
                Assert.AreEqual( "$OBX_7_0_0" , patientLabResult.ReferenceRange );
                Assert.AreEqual( "$OBX_6_0_0" , patientLabResult.Unit );
                //Assert.AreEqual( "$OBX_3_0_0" , patientLabResult.Mnemonic );
                //Assert.AreEqual( "$OBX_11_0_0" , patientLabResult.AbnormalFlag );
'''],
},
'PatientMicrobiologyResults' : {
    'MSH' : ['''
            var patient = GetPatient("$PID_3_0_0");
            if (patient == null) { Assert.Inconclusive("patient not found"); }
            var patientMicrobiologyResultCnt = 0;


                    var patientMicrobiologyResultHistoryDescriptionCnt = 0;
                    var patientMicrobiologyResultHistoryPathogenCnt = 0;
                    var patientMicrobiologyResultHistoryPathogenSensitivityCnt = 0;
                    var patientMicrobiologyResultHistoryScreeningCnt = 0;
    ''','''
/*
Assert.AreEqual(patient.PatientMicrobiologyResults
    .SelectMany(patientMicrobiologyResult => patientMicrobiologyResult.PatientMicrobiologyResultHistories)
    .SelectMany(patientMicrobiologyResultHistory => patientMicrobiologyResultHistory.PatientMicrobiologyResultHistoryDescriptions)
    .Count() , patientMicrobiologyResultHistoryDescriptionCnt);
Assert.AreEqual(patient.PatientMicrobiologyResults
    .SelectMany(patientMicrobiologyResult => patientMicrobiologyResult.PatientMicrobiologyResultHistories)
    .SelectMany(patientMicrobiologyResultHistory => patientMicrobiologyResultHistory.PatientMicrobiologyResultHistoryPathogens)
    .Count() , patientMicrobiologyResultHistoryPathogenCnt);
Assert.AreEqual(patient.PatientMicrobiologyResults
    .SelectMany(patientMicrobiologyResult => patientMicrobiologyResult.PatientMicrobiologyResultHistories)
    .SelectMany(patientMicrobiologyResultHistory => patientMicrobiologyResultHistory.PatientMicrobiologyResultHistoryPathogens)
    .SelectMany(patientMicrobiologyResultHistoryPathogen => patientMicrobiologyResultHistoryPathogen.PatientMicrobiologyResultHistoryPathogenSensitivities)
    .Count() , patientMicrobiologyResultHistoryPathogenSensitivityCnt);
*/
'''],
    'OBR' : ['''
                if (patient.PatientMicrobiologyResults.Count() <= patientMicrobiologyResultCnt)
                {
                    Assert.Inconclusive("PatientMicrobiologyResults not mapped as far as {0}", patientMicrobiologyResultCnt);
                }
                var patientMicrobiologyResult = patient.PatientMicrobiologyResults.ElementAt(patientMicrobiologyResultCnt++);

                //Assert.AreEqual( null , patientMicrobiologyResult.ModificationDate );
                //Assert.AreEqual( null , patientMicrobiologyResult.ModificationUser );

                //Assert.AreEqual( "$OBX_3_0_0" , patientMicrobiologyResult.ExternalCode );
                Assert.AreEqual( "$ORC_3_0_0" ?? "${OBX_5_0_0}$OBX_14_0_0" , patientMicrobiologyResult.ExternalCode, "chicoutimi" );
                //Assert.AreEqual( "$OBX_5_0_0__1" ?? "$OBR_4_1_0 : $OBR_15_0_1 - $OBR_15_3_1" , patientMicrobiologyResult.ProcedureName );
                Assert.AreEqual( null , patientMicrobiologyResult.GroupOrderNumber );
                //Assert.AreEqual( "$OBX_11_0_0" , patientMicrobiologyResult.NosocomialStateKey );
                //Assert.AreEqual( 0 , patientMicrobiologyResult.SampleType );

                //Assert.AreEqual( new DateTime("$MSH_6_0_0") , patientMicrobiologyResult.LastMessageDate );
                //Assert.AreEqual( new DateTime("$OBX_14_0_0") , patientMicrobiologyResult.Date );
                //Assert.AreEqual( new [] { new DateTime("$ORC_9_0_0"), new DateTime("$OBR_22_0_0") ,new DateTime("$OBX_14_0_0"), new DateTime("$OBR_7_0_0")  }.Where(date => date > new DateTime(2000,1,1)).First() , patientMicrobiologyResult.Date, "chicoutimi" );
                var patientMicrobiologyResultHistoryCnt = 0;
''','''
                if("$OBX_11_0_0" != null) // chicoutimi
                {
                    if (patientMicrobiologyResult.PatientMicrobiologyResultHistories.Count() <= patientMicrobiologyResultHistoryCnt)
                    {
                        Assert.Inconclusive("PatientMicrobiologyResultHistory not mapped as far as {0}", patientMicrobiologyResultHistoryCnt);
                    }
                    var patientMicrobiologyResultHistory = patientMicrobiologyResult.PatientMicrobiologyResultHistories.ElementAt(patientMicrobiologyResultHistoryCnt++);

                    //Assert.AreEqual( null , patientMicrobiologyResultHistory.ModificationDate );
                    //Assert.AreEqual( null , patientMicrobiologyResultHistory.ModificationUser );

                    Assert.AreEqual( "$OBX_11_0_0" , patientMicrobiologyResultHistory.ProgressStateKey );

                    //Assert.AreEqual( patientMicrobiologyResult.LastMessageDate , patientMicrobiologyResultHistory.DateOfMessage );
                    //Assert.AreEqual( patientMicrobiologyResult.Date , patientMicrobiologyResultHistory.Date );
                    //Assert.AreEqual( new DateTime("$OBR_14_0_0") , patientMicrobiologyResultHistory.Date , "chicoutimi");
                    //Assert.AreEqual( new DateTime("$OBR_22_0_0") , patientMicrobiologyResultHistory.Date , "chicoutimi");
                    //Assert.AreEqual( new DateTime("$OBX_14_0_0") , patientMicrobiologyResultHistory.Date , "chicoutimi");
                    //Assert.AreEqual( new DateTime("$OBR_7_0_0") , patientMicrobiologyResultHistory.Date , "chicoutimi");
                }
'''],
    'OBX' : ['''
                {
                    if (patient.PatientMicrobiologyResults
                            .SelectMany(patientMicrobiologyResult => patientMicrobiologyResult.PatientMicrobiologyResultHistories)
                            .SelectMany(patientMicrobiologyResultHistory => patientMicrobiologyResultHistory.PatientMicrobiologyResultHistoryDescriptions)
                            .Count() <= patientMicrobiologyResultHistoryDescriptionCnt)
                    {
                        Assert.Inconclusive("PatientMicrobiologyResultHistoryDescriptions not mapped as far as {0}", patientMicrobiologyResultHistoryDescriptionCnt);
                    }
                    var patientMicrobiologyResultHistoryDescription = patient.PatientMicrobiologyResults
                            .SelectMany(patientMicrobiologyResult => patientMicrobiologyResult.PatientMicrobiologyResultHistories)
                            .SelectMany(patientMicrobiologyResultHistory => patientMicrobiologyResultHistory.PatientMicrobiologyResultHistoryDescriptions)
                            .ElementAt(patientMicrobiologyResultHistoryDescriptionCnt++);

                    //Assert.AreEqual( null , patientMicrobiologyResultHistoryDescription.ModificationDate );
                    //Assert.AreEqual( null , patientMicrobiologyResultHistoryDescription.ModificationUser );

                    Assert.AreEqual( "$OBX_3_1_0" , patientMicrobiologyResultHistoryDescription.FieldName );
                    //Assert.AreEqual( "$OBX_5_0_0" , patientMicrobiologyResultHistoryDescription.Description );

                    //Assert.AreEqual( true , patientMicrobiologyResultHistoryDescription.IsVisible );
                    //Assert.AreEqual( 0 , patientMicrobiologyResultHistoryDescription.LineNumber );
                }
''','''
                if("$OBX_2_0_0" == "CE") // chicoutimi
                {
                    if (patient.PatientMicrobiologyResults
                            .SelectMany(patientMicrobiologyResult => patientMicrobiologyResult.PatientMicrobiologyResultHistories)
                            .SelectMany(patientMicrobiologyResultHistory => patientMicrobiologyResultHistory.PatientMicrobiologyResultHistoryPathogens)
                            .Count() <= patientMicrobiologyResultHistoryPathogenCnt)
                    {
                        Assert.Inconclusive("PatientMicrobiologyResultHistoryPathogens not mapped as far as {0}",patientMicrobiologyResultHistoryPathogenCnt);
                    }
                    var patientMicrobiologyResultHistoryPathogen = patient.PatientMicrobiologyResults
                        .SelectMany(patientMicrobiologyResult => patientMicrobiologyResult.PatientMicrobiologyResultHistories)
                        .SelectMany(patientMicrobiologyResultHistory => patientMicrobiologyResultHistory.PatientMicrobiologyResultHistoryPathogens)
                        .ElementAt(patientMicrobiologyResultHistoryPathogenCnt++);

                    //Assert.AreEqual( null , patientMicrobiologyResultHistoryPathogen.ModificationDate );
                    //Assert.AreEqual( null , patientMicrobiologyResultHistoryPathogen.ModificationUser );

                    Assert.AreEqual( "$OBX_5_1_0" , patientMicrobiologyResultHistoryPathogen.PathogenType.SystemName );
                    Assert.AreEqual( "$OBX_5_1_0" , patientMicrobiologyResultHistoryPathogen.OrganismRaw );
                    //Assert.AreEqual( "" , patientMicrobiologyResultHistoryPathogen.OrganismIdentifier );
                    //Assert.AreEqual( "" , patientMicrobiologyResultHistoryPathogen.PathogenType.SpinCode );
                    //Assert.AreEqual( "" , patientMicrobiologyResultHistoryPathogen.PathogenType.MylaCode );

                    Assert.AreEqual( null , patientMicrobiologyResultHistoryPathogen.EnabledTo );
                    //Assert.AreEqual( true , patientMicrobiologyResultHistoryPathogen.IsSuspected );
                    Assert.AreEqual( true , patientMicrobiologyResultHistoryPathogen.IsEnabled );
                    //Assert.AreEqual( patientMicrobiologyResult.Date , patientMicrobiologyResultHistoryPathogen.EnabledFrom );
                }
''','''
                if("$OBX_2_0_0" == "ST")
                {
                    if (patient.PatientMicrobiologyResults
                            .SelectMany(patientMicrobiologyResult => patientMicrobiologyResult.PatientMicrobiologyResultHistories)
                            .SelectMany(patientMicrobiologyResultHistory => patientMicrobiologyResultHistory.PatientMicrobiologyResultHistoryPathogens)
                            .SelectMany(patientMicrobiologyResultHistoryPathogen => patientMicrobiologyResultHistoryPathogen.PatientMicrobiologyResultHistoryPathogenSensitivities)
                            .Count() <= patientMicrobiologyResultHistoryPathogenSensitivityCnt)
                    {
                        Assert.Inconclusive("PatientMicrobiologyResultHistoryPathogenSensitivities not mapped");
                    }
                    var patientMicrobiologyResultHistoryPathogenSensitivity = patient.PatientMicrobiologyResults
                        .SelectMany(patientMicrobiologyResult => patientMicrobiologyResult.PatientMicrobiologyResultHistories)
                        .SelectMany(patientMicrobiologyResultHistory => patientMicrobiologyResultHistory.PatientMicrobiologyResultHistoryPathogens)
                        .SelectMany(patientMicrobiologyResultHistoryPathogen => patientMicrobiologyResultHistoryPathogen.PatientMicrobiologyResultHistoryPathogenSensitivities)
                        .ElementAt(patientMicrobiologyResultHistoryPathogenSensitivityCnt++);

                    //Assert.AreEqual( null , patientMicrobiologyResultHistoryPathogenSensitivity.ModificationDate );
                    //Assert.AreEqual( null , patientMicrobiologyResultHistoryPathogenSensitivity.ModificationUser );

                    Assert.AreEqual( "$OBX_3_1_0" , patientMicrobiologyResultHistoryPathogenSensitivity.MedicationRaw );
                    Assert.AreEqual( "$OBX_8_0_0" , patientMicrobiologyResultHistoryPathogenSensitivity.SensitivityRaw );
                    //Assert.AreEqual( "$OBX_8_0_0" , patientMicrobiologyResultHistoryPathogenSensitivity.Sensitivity );
                    Assert.AreEqual( "$OBX_5_0_0" , patientMicrobiologyResultHistoryPathogenSensitivity.MicValue );
                    //Assert.AreEqual( "$NTE_3_0_0" , patientMicrobiologyResultHistoryPathogenSensitivity.Notes );
                    //Assert.AreEqual( "$OBX_3_1_0" , patientMicrobiologyResultHistoryPathogenSensitivity.MedicationType.SystemName );

                    //Assert.AreEqual( patientMicrobiologyResult.Date , patientMicrobiologyResultHistoryPathogenSensitivity.EnabledFrom );

                    Assert.AreEqual( true , patientMicrobiologyResultHistoryPathogenSensitivity.IsEnabled );
                    Assert.AreEqual( null , patientMicrobiologyResultHistoryPathogenSensitivity.EnabledTo );
                    Assert.AreEqual( null , patientMicrobiologyResultHistoryPathogenSensitivity.NonReportable );
                    //Assert.AreEqual( true , patientMicrobiologyResultHistoryPathogenSensitivity.MedicationType.IsAntibiotic );
                }
''','''
                {
                    if (patient.PatientMicrobiologyResults
                            .SelectMany(patientMicrobiologyResult => patientMicrobiologyResult.PatientMicrobiologyResultHistories)
                            .SelectMany(patientMicrobiologyResultHistory => patientMicrobiologyResultHistory.PatientMicrobiologyResultHistoryScreenings)
                            .Count() <= patientMicrobiologyResultHistoryScreeningCnt)
                    {
                        Assert.Inconclusive("PatientMicrobiologyResultHistoryScreenings not mapped");
                    }
                    var patientMicrobiologyResultHistoryScreening = patient.PatientMicrobiologyResults
                        .SelectMany(patientMicrobiologyResult => patientMicrobiologyResult.PatientMicrobiologyResultHistories)
                        .SelectMany(patientMicrobiologyResultHistory => patientMicrobiologyResultHistory.PatientMicrobiologyResultHistoryScreenings)
                        .ElementAt(patientMicrobiologyResultHistoryScreeningCnt++);

                    //Assert.AreEqual( null , patientMicrobiologyResultHistoryScreening.ModificationUser );
                    //Assert.AreEqual( null , patientMicrobiologyResultHistoryScreening.ModificationDate );

                    Assert.AreEqual( "" , patientMicrobiologyResultHistoryScreening.InfectionType.InfectionTypeKey );
                    Assert.AreEqual( "" , patientMicrobiologyResultHistoryScreening.ScreeningStateKey );
                    Assert.AreEqual( "" , patientMicrobiologyResultHistoryScreening.InfectionTypeKey );

                    //Assert.AreEqual( patientMicrobiologyResult.Date , patientMicrobiologyResultHistoryScreening.EnabledFrom );
                    Assert.AreEqual( null , patientMicrobiologyResultHistoryScreening.EnabledTo );
                    Assert.AreEqual( true , patientMicrobiologyResultHistoryScreening.IsEnabled );
                
                }
''']
}
})

if __name__ == '__main__':
    src = 'hl7.db'
    if len(sys.argv) > 1:
        src = sys.argv[1]

    for src,seq,theShit in floodTheShit(src):
        d = dict(
                test='', 
                tests={},
                src = src,
                seq = seq
            )
        for row,seg,dick in theShit:
            #if seg == 'MSH':
            #    d['name'] = string.Template('${MSH_2_0_0}_${MSH_2_1_0}_${MSH_6_0_0}_${MSH_8_0_0}_${MSH_8_1_0}_${src}_${seq}').safe_substitute(dick)
            #    #sanitize filename
            #    d['name'] = re.sub(r'\$\{?[A-Z][A-Z]{2}(_[0-9]+){3}\}?','',d['name'])
            for testName in templateCatalog:
                t = d['tests'][testName] if testName in d['tests'] else ''
                if seg in templateCatalog[testName]:
                    ttt = ''
                    for tpl in templateCatalog[testName][seg]:
                        tt = string.Template(tpl).safe_substitute(dick)
                        if tt != tpl or seg == 'MSH':
                            # if havent changed at all, no match
                            ttt = ttt + tt
                    # clean up same segment unused tag
                    t = re.sub(r'"\$\{?'+seg+'(_[0-9]+){3}(__[0-9]+)?\}?"','null',t)
                    if ttt:
                        if seg != 'MSH':
                            t = t + '\n' + ' '*12 + '{\n' + ttt + '\n' +' '*12 + '}\n'
                        else:
                            t = t + ttt
                #maybe and OBX refer to the next NTE
                d['tests'][testName] = string.Template(t).safe_substitute(dick)

        d['name'] = string.Template('${MSH_2_0_0}_${MSH_2_1_0}_${PID_3_0_0}_${MSH_6_0_0}_${MSH_8_0_0}_${MSH_8_1_0}').safe_substitute(dick)
        #sanitize filename
        d['name'] = re.sub(r'\$\{?[A-Z][A-Z]{2}(_[0-9]+){3}\}?','',d['name'])
        #wrap c# unit test method
        for testName in templateCatalog:
            dtpl = '''
        [TestMethod]
        public void ${name}_Test()
        {
$test
        }
            '''
            dtest = string.Template(dtpl).safe_substitute(test=d['tests'][testName], name=testName)
            if len(dtest) - 200 > len(dtpl):
                d['test'] = d['test'] + dtest
        #wrap c# unit test class
        d['test'] = string.Template('''
using Lumed.Common.Data;
using Lumed.Data.Entity;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Data.Entity;
using System.Linq;

namespace Importer.IntegrationTests.Analysis
{
    [TestClass]
    public class ${name}_Tests
    {
$test

        private Patient GetPatient(string externalCode)
        {
            using (var dbContext = new CommonEntities())
            {
                return dbContext
                    .DisableLazyLoading()
                    .Patients
                    .AsNoTracking()
                    .Include(patient => patient.PatientExternalCodes)
                    .Include(patient => patient.PatientHospitalizations)
                    .Include(patient => patient.PatientHospitalizations.Select(patientHospitalization => patientHospitalization.PatientHospitalizationBeds))
                    .Include(patient => patient.PatientHospitalizations.Select(patientHospitalization => patientHospitalization.PatientHospitalizationBeds.Select(patientHospitalizationBed => patientHospitalizationBed.Bed.Room)))
                    .Include(patient => patient.PatientHospitalizations.Select(patientHospitalization => patientHospitalization.PatientHospitalizationBeds.Select(patientHospitalizationBed => patientHospitalizationBed.HospitalUnit.Hospital)))
                    .Include(patient => patient.PatientHospitalizations.Select(patientHospitalization => patientHospitalization.PatientHospitalizationPhysicians))
                    .Include(patient => patient.PatientHospitalizations.Select(patientHospitalization => patientHospitalization.PatientHospitalizationPhysicians.Select(patientHospitalizationPhysician => patientHospitalizationPhysician.Physician)))
                    .Include(patient => patient.PatientHospitalizations.Select(patientHospitalization => patientHospitalization.PatientHospitalizationReasonOfAdmissions))
                    .Include(patient => patient.PatientLabResults)
                    .Include(patient => patient.PatientLabOrders.Select(labOrder => labOrder.PatientLabResults))
                    .Include(patient => patient.PatientLabOrders.Select(labOrder => labOrder.PatientSerumLevels))
                    .Include(patient => patient.PatientMicrobiologyResults.Select(patientMicrobiologyResult => patientMicrobiologyResult.CurrentPatientMicrobiologyResultHistory))
                    .Include(patient => patient.PatientMicrobiologyResults.Select(patientMicrobiologyResult => patientMicrobiologyResult.CurrentPatientMicrobiologyResultHistory.PatientMicrobiologyResultHistoryDescriptions))
                    .Include(patient => patient.PatientMicrobiologyResults.Select(patientMicrobiologyResult => patientMicrobiologyResult.CurrentPatientMicrobiologyResultHistory.PatientMicrobiologyResultHistoryPathogens))
                    .Include(patient => patient.PatientMicrobiologyResults.Select(patientMicrobiologyResult => patientMicrobiologyResult.CurrentPatientMicrobiologyResultHistory.PatientMicrobiologyResultHistoryPathogens.Select(patientMicrobiologyResultHistoryPathogen => patientMicrobiologyResultHistoryPathogen.PathogenType)))
                    .Include(patient => patient.PatientMicrobiologyResults.Select(patientMicrobiologyResult => patientMicrobiologyResult.CurrentPatientMicrobiologyResultHistory.PatientMicrobiologyResultHistoryPathogens.Select(patientMicrobiologyResultHistoryPathogen => patientMicrobiologyResultHistoryPathogen.PatientMicrobiologyResultHistoryPathogenSensitivities.Select(patientMicrobiologyPathogenSensivity => patientMicrobiologyPathogenSensivity.MedicationType))))
                    .Include(patient => patient.PatientMicrobiologyResults.Select(patientMicrobiologyResult => patientMicrobiologyResult.CurrentPatientMicrobiologyResultHistory.PatientMicrobiologyResultHistoryPathogens.Select(patientMicrobiologyResultHistoryPathogen => patientMicrobiologyResultHistoryPathogen.PatientMicrobiologyResultHistoryPathogenSensitivities)))
                    .Include(patient => patient.PatientMicrobiologyResults.Select(patientMicrobiologyResult => patientMicrobiologyResult.CurrentPatientMicrobiologyResultHistory.PatientMicrobiologyResultHistoryScreenings))
                    .Include(patient => patient.PatientMicrobiologyResults.Select(patientMicrobiologyResult => patientMicrobiologyResult.PatientMicrobiologyResultHistories))
                    .Include(patient => patient.PatientMicrobiologyResults.Select(patientMicrobiologyResult => patientMicrobiologyResult.PatientMicrobiologyResultHistories.Select(patientMicrobiologyResultHistory => patientMicrobiologyResultHistory.PatientMicrobiologyResultHistoryDescriptions)))
                    .Include(patient => patient.PatientMicrobiologyResults.Select(patientMicrobiologyResult => patientMicrobiologyResult.PatientMicrobiologyResultHistories.Select(patientMicrobiologyResultHistory => patientMicrobiologyResultHistory.PatientMicrobiologyResultHistoryPathogens)))
                    .Include(patient => patient.PatientMicrobiologyResults.Select(patientMicrobiologyResult => patientMicrobiologyResult.PatientMicrobiologyResultHistories.Select(patientMicrobiologyResultHistory => patientMicrobiologyResultHistory.PatientMicrobiologyResultHistoryPathogens.Select(patientMicrobiologyResultHistoryPathogen => patientMicrobiologyResultHistoryPathogen.PathogenType))))
                    .Include(patient => patient.PatientMicrobiologyResults.Select(patientMicrobiologyResult => patientMicrobiologyResult.PatientMicrobiologyResultHistories.Select(patientMicrobiologyResultHistory => patientMicrobiologyResultHistory.PatientMicrobiologyResultHistoryPathogens.Select(patientMicrobiologyResultHistoryPathogen => patientMicrobiologyResultHistoryPathogen.PatientMicrobiologyResultHistoryPathogenSensitivities.Select(patientMicrobiologyPathogenSensivity => patientMicrobiologyPathogenSensivity.MedicationType)))))
                    .Include(patient => patient.PatientMicrobiologyResults.Select(patientMicrobiologyResult => patientMicrobiologyResult.PatientMicrobiologyResultHistories.Select(patientMicrobiologyResultHistory => patientMicrobiologyResultHistory.PatientMicrobiologyResultHistoryPathogens.Select(patientMicrobiologyResultHistoryPathogen => patientMicrobiologyResultHistoryPathogen.PatientMicrobiologyResultHistoryPathogenSensitivities))))
                    .Include(patient => patient.PatientMicrobiologyResults.Select(patientMicrobiologyResult => patientMicrobiologyResult.PatientMicrobiologyResultHistories.Select(patientMicrobiologyResultHistory => patientMicrobiologyResultHistory.PatientMicrobiologyResultHistoryScreenings)))
                    .FirstOrDefault(patient => patient.PatientExternalCodes.Any(p => p.ExternalCode == externalCode));
            }
        }
    }
}
        ''').safe_substitute(d)

        t = d['test']
        #clean up unused token
        t = re.sub(r'"\$\{?[A-Z][A-Z0-9]{2}(_[0-9]+){3}(__[0-9]+)?\}?"','null',t)
        #date are better that way
        t = re.sub(r'DateTime\(""\)', r'DateTime()', t)
        t = re.sub(r'DateTime\(null\)', r'DateTime()', t)
        t = re.sub(r'DateTime\("([0-9]{4})([0-9]{2})([0-9]{2})"\)', r'DateTime(\1, \2, \3)', t)
        t = re.sub(r'DateTime\("([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})"\)', r'DateTime(\1, \2, \3, \4, \5, 0)', t)
        t = re.sub(r'DateTime\("([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})"\)', r'DateTime(\1, \2, \3, \4, \5, \6)', t)
        #chicoutimi do wierd thing
        t = re.sub(r'GetPatient\("[CP]([A-Z][^"]*)"\)', r'GetPatient("\1")', t)
        t = re.sub(r'AreEqual\( "[CP]([A-Z][^"]*)" , patientExternalCode.ExternalCode \)', r'AreEqual( "\1" , patientExternalCode.ExternalCode )', t)
        #sanitize generated text
        #t = re.sub(r'\\S\\',r'\\\\S\\\\',t) # hl7 escaped character
        #t = re.sub(r'\\.br\\',r'\\\\.br\\\\',t) # hl7 escaped character
        t = re.sub(r'\\',r'\\\\',t) # hl7 escaped character
        t = re.sub(r'""""',r'""',t) # hl7 escaped character
        d['test'] = t
        import os
        if not os.path.exists('AnalyseTests'):
            os.makedirs('AnalyseTests')
        open('AnalyseTests/'+d['name']+'.cs','w').write(d['test'])
        print(d['name'])

