// File: /workspace/github_c_makefile_star2_O1/giannisdravilas[P]Disease-Monitor/tests/../modules/DiseaseMonitor.c
// Function: dm_top_diseases
List dm_top_diseases(int k, String country){

    MapNode node = map_find_node(map_countries_dates, country);

    // Αν βρούμε τη χώρα στο map και αυτή δεν είναι NULL, δημιουργούμε ένα καινούριο map_country_diseases
    // στο οποίο εισάγουμε όλες τις ασθένειες που περιλαμβάνονται στο Set της συγκεκριμένης χώρας.
    // Οι for() διατρέχουν μόνο το set της συγκεκριμένης χώρας, δεν εξαρτώνται δηλαδή από το συνολικό πλήθος
    // εγγραφών, αφού σε πρακτικές χρήσεις θεωρούμε ότι θα υπάρχουν παραπάνω από μία χώρες.
    if(node){
        if(country){
            map_country_diseases = map_create(compare_diseases, NULL, free);
            map_set_hash_function(map_country_diseases, hash_string);
            Set set = map_node_value(map_countries_dates, node);
            for(SetNode node_set = set_first(set); node_set != SET_EOF; node_set = set_next(set, node_set)){
                Record record = set_node_value(set, node_set);
                map_insert(map_country_diseases, record->disease, create_int(0));
            }

            // Έπειτα ενημερώνουμε το πλήθος εγγραφών για κάθε ασθένεια
            for(SetNode node_set = set_first(set); node_set != SET_EOF; node_set = set_next(set, node_set)){
                Record record = set_node_value(set, node_set);
                Pointer value = map_find(map_country_diseases, record->disease);
                (*(int*)value)++;
            }

            // Εισάγουμε τα στοιχεία σε μια Priority Queue, στην οποία ταξινομούνται με βάση τα values του Map
            PriorityQueue pqueue = pqueue_create(compare_diseases_counter, NULL, NULL);
            for(MapNode node_map = map_first(map_country_diseases); node_map != MAP_EOF; node_map = map_next(map_country_diseases, node_map)){
                pqueue_insert(pqueue, map_node_key(map_country_diseases, node_map));
            }

            // Δημιουργούμε μια λίστα και εισάγουμε τα στοιχεία της Priority Queue
            List list = list_create(NULL);
            while(pqueue_size(pqueue) && k--){
                list_insert_next(list, list_last(list), pqueue_max(pqueue));
                pqueue_remove_max(pqueue);
            }

            pqueue_destroy(pqueue);
            map_destroy(map_country_diseases);

            return list;
        }

    // Αν country == NULL χρησιμοποιούμε το map_NULL_diseases και εισάγουμε τα στοιχεία του σε μια Priority Queue
    // κι έπειτα στη λίστα
    }else if(!country){

        List list = list_create(NULL);

        PriorityQueue pqueue = pqueue_create(compare_NULL_diseases, NULL, NULL);
        for(MapNode node_map = map_first(map_NULL_diseases); node_map != MAP_EOF; node_map = map_next(map_NULL_diseases, node_map)){
            pqueue_insert(pqueue, map_node_key(map_NULL_diseases, node_map));
        }

        while(pqueue_size(pqueue) && k--){
            list_insert_next(list, list_last(list), pqueue_max(pqueue));
            pqueue_remove_max(pqueue);
        }

        pqueue_destroy(pqueue);

        return list;
    }
    
    return NULL;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movq %rsi, %r15
movl %edi, %ebx
movq 0x8979(%rip), %rdi      # 0xe740
callq 0x6f25
testq %rax, %rax
je 0x5f87
testq %r15, %r15
je 0x5f8c
movq %rax, %r14
leaq -0x1277(%rip), %rdi     # 0x4b71
movq 0x81d1(%rip), %rdx      # 0xdfc0
xorl %esi, %esi
callq 0x645c
movq %rax, 0x8923(%rip)      # 0xe720
leaq 0x1226(%rip), %rsi      # 0x702a
movq %rax, %rdi
callq 0x700b
movq 0x892d(%rip), %rdi      # 0xe740
movq %r14, %rsi
callq 0x6f0b
movq %rax, %r14
movq %rax, %rdi
callq 0x8336
testq %rax, %rax
je 0x5e75
movq %rax, %r15
movq %r14, %rdi
movq %r15, %rsi
callq 0x83e0
movq 0x88e0(%rip), %r12      # 0xe720
movq 0x10(%rax), %r13
movl $0x4, %edi
callq 0x21c0
movl $0x0, (%rax)
movq %r12, %rdi
movq %r13, %rsi
movq %rax, %rdx
callq 0x6736
movq %r14, %rdi
movq %r15, %rsi
callq 0x83ac
movq %rax, %r15
testq %rax, %rax
jne 0x5e2e
movq %r14, %rdi
callq 0x8336
testq %rax, %rax
je 0x5eb5
movq %rax, %r15
movq %r14, %rdi
movq %r15, %rsi
callq 0x83e0
movq 0x8889(%rip), %rdi      # 0xe720
movq 0x10(%rax), %rsi
callq 0x6abd
incl (%rax)
movq %r14, %rdi
movq %r15, %rsi
callq 0x83ac
movq %rax, %r15
testq %rax, %rax
jne 0x5e85
leaq -0x12c1(%rip), %rdi     # 0x4bfb
xorl %esi, %esi
xorl %edx, %edx
callq 0x73c0
movq %rax, %r15
movq 0x8851(%rip), %rdi      # 0xe720
callq 0x6c9f
testq %rax, %rax
je 0x5f0d
movq %rax, %r14
movq 0x883d(%rip), %rdi      # 0xe720
movq %r14, %rsi
callq 0x6ef2
movq %r15, %rdi
movq %rax, %rsi
callq 0x749e
movq 0x8823(%rip), %rdi      # 0xe720
movq %r14, %rsi
callq 0x6d5b
movq %rax, %r14
testq %rax, %rax
jne 0x5edc
xorl %edi, %edi
callq 0x6062
movq %rax, %r14
movq %r15, %rdi
callq 0x745a
testl %eax, %eax
sete %al
testl %ebx, %ebx
sete %cl
orb %al, %cl
jne 0x5f6e
decl %ebx
movq %r14, %rdi
callq 0x6341
movq %rax, %r12
movq %r15, %rdi
callq 0x747b
movq %r14, %rdi
movq %r12, %rsi
movq %rax, %rdx
callq 0x60e3
movq %r15, %rdi
callq 0x7525
movq %r15, %rdi
callq 0x745a
subl $0x1, %ebx
setb %cl
testl %eax, %eax
je 0x5f6e
testb %cl, %cl
je 0x5f2f
movq %r15, %rdi
callq 0x7630
movq 0x87a3(%rip), %rdi      # 0xe720
callq 0x6b5c
jmp 0x6055
testq %r15, %r15
je 0x5f94
xorl %r14d, %r14d
jmp 0x6055
xorl %edi, %edi
callq 0x6062
movq %rax, %r14
leaq -0x1379(%rip), %rdi     # 0x4c2c
xorl %esi, %esi
xorl %edx, %edx
callq 0x73c0
movq %rax, %r15
movq 0x8770(%rip), %rdi      # 0xe728
callq 0x6c9f
testq %rax, %rax
je 0x5ff6
movq %rax, %r12
movq 0x875c(%rip), %rdi      # 0xe728
movq %r12, %rsi
callq 0x6ef2
movq %r15, %rdi
movq %rax, %rsi
callq 0x749e
movq 0x8742(%rip), %rdi      # 0xe728
movq %r12, %rsi
callq 0x6d5b
movq %rax, %r12
testq %rax, %rax
jne 0x5fc5
movq %r15, %rdi
callq 0x745a
testl %eax, %eax
sete %al
testl %ebx, %ebx
sete %cl
orb %al, %cl
jne 0x604d
decl %ebx
movq %r14, %rdi
callq 0x6341
movq %rax, %r12
movq %r15, %rdi
callq 0x747b
movq %r14, %rdi
movq %r12, %rsi
movq %rax, %rdx
callq 0x60e3
movq %r15, %rdi
callq 0x7525
movq %r15, %rdi
callq 0x745a
subl $0x1, %ebx
setb %cl
testl %eax, %eax
je 0x604d
testb %cl, %cl
je 0x600e
movq %r15, %rdi
callq 0x7630
movq %r14, %rax
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq