// File: /workspace/github_c_makefile_star2_O2/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 0x9b8f(%rip), %rdi      # 0xe710
movq %r14, %rsi
callq 0x69ed
movq %rax, %rbx
movq 0x9b7d(%rip), %rdi      # 0xe710
testq %rax, %rax
je 0x4ccb
movq %rbx, %rsi
callq 0x69d3
movq %rax, %r15
pushq $0x18
popq %rdi
callq 0x21b0
movq %rax, %r12
movups 0x10(%r15), %xmm0
movups %xmm0, (%rax)
movq 0x20(%r15), %rax
movq %rax, 0x10(%r12)
movq 0x9b5e(%rip), %rdi      # 0xe728
movq %r12, %rsi
callq 0x6585
decl (%rax)
movq 0x9b2d(%rip), %rdi      # 0xe708
movq 0x10(%r15), %rsi
callq 0x6585
decl (%rax)
movq %r12, %rdi
callq 0x22c0
movq 0x9b1b(%rip), %rdi      # 0xe710
movq %r14, %rsi
callq 0x63fe
movq 0x9b0c(%rip), %rdi      # 0xe710
movq %r14, %rsi
movq %r14, %rdx
callq 0x61fe
movq 0x9b02(%rip), %rdi      # 0xe718
movq 0x10(%r14), %rsi
callq 0x69ed
testq %rax, %rax
je 0x4c5b
movq %rax, %r15
movq 0x9aea(%rip), %rdi      # 0xe718
movq %rax, %rsi
callq 0x69d3
movq %rax, %rdi
movq %r14, %rsi
callq 0x7ca0
movq 0x9ad0(%rip), %rdi      # 0xe718
movq %r15, %rsi
callq 0x69d3
movq %rax, %rdi
movq %r14, %rsi
callq 0x7c00
movq 0x9abe(%rip), %rdi      # 0xe720
movq 0x18(%r14), %rsi
callq 0x69ed
testq %rax, %rax
je 0x4ca7
movq %rax, %r15
movq 0x9aa6(%rip), %rdi      # 0xe720
movq %rax, %rsi
callq 0x69d3
movq %rax, %rdi
movq %r14, %rsi
callq 0x7ca0
movq 0x9a8c(%rip), %rdi      # 0xe720
movq %r15, %rsi
callq 0x69d3
movq %rax, %rdi
movq %r14, %rsi
callq 0x7c00
movq 0x9a7a(%rip), %rdi      # 0xe728
movq %r14, %rsi
callq 0x4ad4
movq 0x9a4b(%rip), %rdi      # 0xe708
movq 0x10(%r14), %rsi
callq 0x6585
jmp 0x4daa
movq %r14, %rsi
movq %r14, %rdx
callq 0x61fe
movq 0x9a3b(%rip), %rdi      # 0xe718
movq 0x10(%r14), %rsi
callq 0x69ed
testq %rax, %rax
je 0x4cff
movq 0x9a26(%rip), %rdi      # 0xe718
movq %rax, %rsi
callq 0x69d3
movq %rax, %r15
jmp 0x4d23
leaq -0x557(%rip), %rdi      # 0x47af
xorl %esi, %esi
callq 0x7b6f
movq %rax, %r15
movq 0x9a01(%rip), %rdi      # 0xe718
movq 0x10(%r14), %rsi
movq %rax, %rdx
callq 0x61fe
movq %r15, %rdi
movq %r14, %rsi
callq 0x7c00
movq 0x99eb(%rip), %rdi      # 0xe720
movq 0x18(%r14), %rsi
callq 0x69ed
testq %rax, %rax
je 0x4d57
movq 0x99d6(%rip), %rdi      # 0xe720
movq %rax, %rsi
callq 0x69d3
movq %rax, %r15
jmp 0x4d7b
leaq -0x5af(%rip), %rdi      # 0x47af
xorl %esi, %esi
callq 0x7b6f
movq %rax, %r15
movq 0x99b1(%rip), %rdi      # 0xe720
movq 0x18(%r14), %rsi
movq %rax, %rdx
callq 0x61fe
movq %r15, %rdi
movq %r14, %rsi
callq 0x7c00
movq 0x999b(%rip), %rdi      # 0xe728
movq %r14, %rsi
callq 0x4ad4
movq 0x996c(%rip), %rdi      # 0xe708
movq 0x10(%r14), %rsi
callq 0x6585
testq %rax, %rax
je 0x4dbe
incl (%rax)
testq %rbx, %rbx
setne %al
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
movq 0x9943(%rip), %r15      # 0xe708
movq 0x10(%r14), %r14
pushq $0x1
popq %rdi
callq 0x4891
movq %r15, %rdi
movq %r14, %rsi
movq %rax, %rdx
callq 0x61fe
jmp 0x4dac