// File: /workspace/github_c_makefile_star2_O1/giannisdravilas[P]Disease-Monitor/tests/../modules/DiseaseMonitor.c
// Function: dm_insert_record
bool dm_insert_record(Record record){

    MapNode found_node = map_find_node(map_ids_records, &(record->id));

    // Αν υπάρχει ήδη record με το ίδιο id
    if(found_node){

        // Βρίσκουμε το προηγούμενο record με το ίδιο id
        Record value = map_node_value(map_ids_records, found_node);

        // Αφαιρούμε από τα map_disease_country_date και map_NULL_disease ένα στοιχείο με τα
        // στοιχεία του προηγούμενου record. H map_find() δεν υπάρχει περίπτωση να επιστρέψει
        // NULL αφού σίγουρα θα έχει εισαχθεί τέτοιο στοιχείο και στα δύο Maps
        MapCount mapcount = malloc(sizeof(*mapcount));
        mapcount->disease = value->disease;
        mapcount->country = value->country;
        mapcount->date = value->date;
        (*(int*)map_find(map_disease_country_date, mapcount))--;
        (*(int*)map_find(map_NULL_diseases, value->disease))--;
        free(mapcount);

        // Αφαιρούμε και επανεισάγουμε το αντίστοιχο record και από τα υπόλοιπα maps, εκείνα
        // δηλαδή που χρησιμοποιεί η map_get_records()
        map_remove(map_ids_records, &(record->id));
        map_insert(map_ids_records, &(record->id), record);

        MapNode found = map_find_node(map_diseases_dates, record->disease);
        if(found){
            set_remove(map_node_value(map_diseases_dates, found), record);
            set_insert(map_node_value(map_diseases_dates, found), record);
        }

        found = map_find_node(map_countries_dates, record->country);
        if(found){
            set_remove(map_node_value(map_countries_dates, found), record);
            set_insert(map_node_value(map_countries_dates, found), record);
        }

        // Ενημερώνουμε και τα map_disease_country_date, map_NULL_diseases
        update_map_count(map_disease_country_date, record);

        Pointer value1 = map_find(map_NULL_diseases, record->disease);
        if(value){
            (*(int*)value1)++;
        }else{
            map_insert(map_NULL_diseases, record->disease, create_int(1));
        }

        return true;

    // Αν δεν υπάρχει record με το ίδιο id    
    }else{

        // Εισάγουμε το record στο map_ids_records
        map_insert(map_ids_records, &(record->id), record);

        // Κάθε στοιχείο του map_diseases_dates είναι ένα Set. Αν υπάρχει Set εισάγουμε
        // το record σε αυτό, αλλιώς δημιουργούμε ένα Set και έπειτα εισάγουμε το record.
        MapNode found = map_find_node(map_diseases_dates, record->disease);
        if(found){
            set_insert(map_node_value(map_diseases_dates, found), record);
        }else{
            Set set = set_create(compare_record_dates, NULL);
            map_insert(map_diseases_dates, record->disease, set);
            set_insert(set, record);
        }

        // Κάθε στοιχείο του map_countries_dates είναι ένα Set. Αν υπάρχει Set εισάγουμε
        // το record σε αυτό, αλλιώς δημιουργούμε ένα Set και έπειτα εισάγουμε το record.
        found = map_find_node(map_countries_dates, record->country);
        if(found){
            set_insert(map_node_value(map_countries_dates, found), record);
        }else{
            Set set = set_create(compare_record_dates, NULL);
            map_insert(map_countries_dates, record->country, set);
            set_insert(set, record);
        }

        // Ενημερώνουμε και τα map_disease_country_date, map_NULL_diseases
        update_map_count(map_disease_country_date, record);
        Pointer value = map_find(map_NULL_diseases, record->disease);
        if(value){
            (*(int*)value)++;
        }else{
            map_insert(map_NULL_diseases, record->disease, create_int(1));
        }

        return false;
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %r14
movq 0x97b4(%rip), %rdi      # 0xe730
movq %r14, %rsi
callq 0x6f25
movq %rax, %rbx
movq 0x97a2(%rip), %rdi      # 0xe730
testq %rax, %rax
je 0x50dc
movq %rbx, %rsi
callq 0x6f0b
movq %rax, %r15
movl $0x18, %edi
callq 0x21c0
movq %rax, %r12
movq 0x10(%r15), %rax
movq %rax, (%r12)
movq 0x18(%r15), %rax
movq %rax, 0x8(%r12)
movq 0x20(%r15), %rax
movq %rax, 0x10(%r12)
movq 0x9778(%rip), %rdi      # 0xe748
movq %r12, %rsi
callq 0x6abd
decl (%rax)
movq 0x9747(%rip), %rdi      # 0xe728
movq 0x10(%r15), %rsi
callq 0x6abd
decl (%rax)
movq %r12, %rdi
callq 0x22d0
movq 0x9735(%rip), %rdi      # 0xe730
movq %r14, %rsi
callq 0x6936
movq 0x9726(%rip), %rdi      # 0xe730
movq %r14, %rsi
movq %r14, %rdx
callq 0x6736
movq 0x971c(%rip), %rdi      # 0xe738
movq 0x10(%r14), %rsi
callq 0x6f25
testq %rax, %rax
je 0x5061
movq %rax, %r12
movq 0x9704(%rip), %rdi      # 0xe738
movq %rax, %rsi
callq 0x6f0b
movq %rax, %rdi
movq %r14, %rsi
callq 0x81d8
movq 0x96ea(%rip), %rdi      # 0xe738
movq %r12, %rsi
callq 0x6f0b
movq %rax, %rdi
movq %r14, %rsi
callq 0x8138
movq 0x96d8(%rip), %rdi      # 0xe740
movq 0x18(%r14), %rsi
callq 0x6f25
testq %rax, %rax
je 0x50ad
movq %rax, %r12
movq 0x96c0(%rip), %rdi      # 0xe740
movq %rax, %rsi
callq 0x6f0b
movq %rax, %rdi
movq %r14, %rsi
callq 0x81d8
movq 0x96a6(%rip), %rdi      # 0xe740
movq %r12, %rsi
callq 0x6f0b
movq %rax, %rdi
movq %r14, %rsi
callq 0x8138
movq 0x9694(%rip), %rdi      # 0xe748
movq %r14, %rsi
callq 0x4ec5
movq 0x9665(%rip), %rdi      # 0xe728
movq 0x10(%r14), %rsi
callq 0x6abd
testq %r15, %r15
je 0x51bf
incl (%rax)
jmp 0x51e8
movq %r14, %rsi
movq %r14, %rdx
callq 0x6736
movq 0x964a(%rip), %rdi      # 0xe738
movq 0x10(%r14), %rsi
callq 0x6f25
testq %rax, %rax
je 0x5110
movq 0x9635(%rip), %rdi      # 0xe738
movq %rax, %rsi
callq 0x6f0b
movq %rax, %r15
jmp 0x5134
leaq -0x59c(%rip), %rdi      # 0x4b7b
xorl %esi, %esi
callq 0x80a7
movq %rax, %r15
movq 0x9610(%rip), %rdi      # 0xe738
movq 0x10(%r14), %rsi
movq %rax, %rdx
callq 0x6736
movq %r15, %rdi
movq %r14, %rsi
callq 0x8138
movq 0x95fa(%rip), %rdi      # 0xe740
movq 0x18(%r14), %rsi
callq 0x6f25
testq %rax, %rax
je 0x5168
movq 0x95e5(%rip), %rdi      # 0xe740
movq %rax, %rsi
callq 0x6f0b
movq %rax, %r15
jmp 0x518c
leaq -0x5f4(%rip), %rdi      # 0x4b7b
xorl %esi, %esi
callq 0x80a7
movq %rax, %r15
movq 0x95c0(%rip), %rdi      # 0xe740
movq 0x18(%r14), %rsi
movq %rax, %rdx
callq 0x6736
movq %r15, %rdi
movq %r14, %rsi
callq 0x8138
movq 0x95aa(%rip), %rdi      # 0xe748
movq %r14, %rsi
callq 0x4ec5
movq 0x957b(%rip), %rdi      # 0xe728
movq 0x10(%r14), %rsi
callq 0x6abd
testq %rax, %rax
jne 0x50d5
movq 0x9562(%rip), %r15      # 0xe728
movq 0x10(%r14), %r14
movl $0x4, %edi
callq 0x21c0
movl $0x1, (%rax)
movq %r15, %rdi
movq %r14, %rsi
movq %rax, %rdx
callq 0x6736
testq %rbx, %rbx
setne %al
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq