// File: /workspace/github_c_makefile_star2_O2/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 0x8e3f(%rip), %rdi      # 0xe720
callq 0x69ed
testq %rax, %rax
je 0x5a6d
testq %r15, %r15
je 0x5a72
movq %rax, %r14
leaq -0x115d(%rip), %rdi     # 0x47a5
movq 0x86b7(%rip), %rdx      # 0xdfc0
xorl %esi, %esi
callq 0x5f24
movq %rax, 0x8de9(%rip)      # 0xe700
leaq 0x11d4(%rip), %rsi      # 0x6af2
movq %rax, %rdi
callq 0x6ad3
movq 0x8df3(%rip), %rdi      # 0xe720
movq %r14, %rsi
callq 0x69d3
movq %rax, %r14
movq %rax, %rdi
callq 0x7dfe
movq %rax, %r15
movq %r14, %rdi
testq %rax, %rax
je 0x5980
movq %r15, %rsi
callq 0x7ea8
movq 0x8da6(%rip), %r12      # 0xe700
movq 0x10(%rax), %r13
xorl %edi, %edi
callq 0x4891
movq %r12, %rdi
movq %r13, %rsi
movq %rax, %rdx
callq 0x61fe
movq %r14, %rdi
movq %r15, %rsi
callq 0x7e74
jmp 0x5940
callq 0x7dfe
movq %rax, %r15
testq %rax, %rax
je 0x59b7
movq %r14, %rdi
movq %r15, %rsi
callq 0x7ea8
movq 0x8d61(%rip), %rdi      # 0xe700
movq 0x10(%rax), %rsi
callq 0x6585
incl (%rax)
movq %r14, %rdi
movq %r15, %rsi
callq 0x7e74
jmp 0x5985
leaq -0x118f(%rip), %rdi     # 0x482f
xorl %esi, %esi
xorl %edx, %edx
callq 0x6e88
movq %rax, %r15
movq 0x8d2f(%rip), %rdi      # 0xe700
callq 0x6767
movq %rax, %r14
testq %rax, %rax
je 0x5a09
movq 0x8d1b(%rip), %rdi      # 0xe700
movq %r14, %rsi
callq 0x69ba
movq %r15, %rdi
movq %rax, %rsi
callq 0x6f66
movq 0x8d01(%rip), %rdi      # 0xe700
movq %r14, %rsi
callq 0x6823
jmp 0x59d6
xorl %edi, %edi
callq 0x5b2a
movq %rax, %r14
movq %r15, %rdi
callq 0x6f22
subl $0x1, %ebx
setb %cl
testl %eax, %eax
je 0x5a54
testb %cl, %cl
jne 0x5a54
movq %r14, %rdi
callq 0x5e09
movq %rax, %r12
movq %r15, %rdi
callq 0x6f43
movq %r14, %rdi
movq %r12, %rsi
movq %rax, %rdx
callq 0x5bab
movq %r15, %rdi
callq 0x6fed
jmp 0x5a13
movq %r15, %rdi
callq 0x70f8
movq 0x8c9d(%rip), %rdi      # 0xe700
callq 0x6624
jmp 0x5b1d
testq %r15, %r15
je 0x5a7a
xorl %r14d, %r14d
jmp 0x5b1d
xorl %edi, %edi
callq 0x5b2a
movq %rax, %r14
leaq -0x122b(%rip), %rdi     # 0x4860
xorl %esi, %esi
xorl %edx, %edx
callq 0x6e88
movq %rax, %r15
movq 0x8c6a(%rip), %rdi      # 0xe708
callq 0x6767
movq %rax, %r12
testq %rax, %rax
je 0x5b03
movq 0x8c56(%rip), %rdi      # 0xe708
movq %r12, %rsi
callq 0x69ba
movq %r15, %rdi
movq %rax, %rsi
callq 0x6f66
movq 0x8c3c(%rip), %rdi      # 0xe708
movq %r12, %rsi
callq 0x6823
jmp 0x5aa3
testb %cl, %cl
jne 0x5b15
movq %r14, %rdi
callq 0x5e09
movq %rax, %r12
movq %r15, %rdi
callq 0x6f43
movq %r14, %rdi
movq %r12, %rsi
movq %rax, %rdx
callq 0x5bab
movq %r15, %rdi
callq 0x6fed
movq %r15, %rdi
callq 0x6f22
subl $0x1, %ebx
setb %cl
testl %eax, %eax
jne 0x5ad6
movq %r15, %rdi
callq 0x70f8
movq %r14, %rax
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq