// File: /workspace/github_c_makefile_star2_O3/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 0x8ac9(%rip), %rdi      # 0xe740
callq 0x6dd5
testq %rax, %rax
je 0x5e37
testq %r15, %r15
je 0x5e3c
movq %rax, %r14
leaq -0x125b(%rip), %rdi     # 0x4a3d
movq 0x8321(%rip), %rdx      # 0xdfc0
xorl %esi, %esi
callq 0x630c
movq %rax, 0x8a73(%rip)      # 0xe720
leaq 0x1226(%rip), %rsi      # 0x6eda
movq %rax, %rdi
callq 0x6ebb
movq 0x8a7d(%rip), %rdi      # 0xe740
movq %r14, %rsi
callq 0x6dbb
movq %rax, %r14
movq %rax, %rdi
callq 0x81e6
testq %rax, %rax
je 0x5d25
movq %rax, %r15
movq %r14, %rdi
movq %r15, %rsi
callq 0x8290
movq 0x8a30(%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 0x65e6
movq %r14, %rdi
movq %r15, %rsi
callq 0x825c
movq %rax, %r15
testq %rax, %rax
jne 0x5cde
movq %r14, %rdi
callq 0x81e6
testq %rax, %rax
je 0x5d65
movq %rax, %r15
movq %r14, %rdi
movq %r15, %rsi
callq 0x8290
movq 0x89d9(%rip), %rdi      # 0xe720
movq 0x10(%rax), %rsi
callq 0x696d
incl (%rax)
movq %r14, %rdi
movq %r15, %rsi
callq 0x825c
movq %rax, %r15
testq %rax, %rax
jne 0x5d35
leaq -0x12a5(%rip), %rdi     # 0x4ac7
xorl %esi, %esi
xorl %edx, %edx
callq 0x7270
movq %rax, %r15
movq 0x89a1(%rip), %rdi      # 0xe720
callq 0x6b4f
testq %rax, %rax
je 0x5dbd
movq %rax, %r14
movq 0x898d(%rip), %rdi      # 0xe720
movq %r14, %rsi
callq 0x6da2
movq %r15, %rdi
movq %rax, %rsi
callq 0x734e
movq 0x8973(%rip), %rdi      # 0xe720
movq %r14, %rsi
callq 0x6c0b
movq %rax, %r14
testq %rax, %rax
jne 0x5d8c
xorl %edi, %edi
callq 0x5f12
movq %rax, %r14
movq %r15, %rdi
callq 0x730a
testl %eax, %eax
sete %al
testl %ebx, %ebx
sete %cl
orb %al, %cl
jne 0x5e1e
decl %ebx
movq %r14, %rdi
callq 0x61f1
movq %rax, %r12
movq %r15, %rdi
callq 0x732b
movq %r14, %rdi
movq %r12, %rsi
movq %rax, %rdx
callq 0x5f93
movq %r15, %rdi
callq 0x73d5
movq %r15, %rdi
callq 0x730a
subl $0x1, %ebx
setb %cl
testl %eax, %eax
je 0x5e1e
testb %cl, %cl
je 0x5ddf
movq %r15, %rdi
callq 0x74e0
movq 0x88f3(%rip), %rdi      # 0xe720
callq 0x6a0c
jmp 0x5f05
testq %r15, %r15
je 0x5e44
xorl %r14d, %r14d
jmp 0x5f05
xorl %edi, %edi
callq 0x5f12
movq %rax, %r14
leaq -0x135d(%rip), %rdi     # 0x4af8
xorl %esi, %esi
xorl %edx, %edx
callq 0x7270
movq %rax, %r15
movq 0x88c0(%rip), %rdi      # 0xe728
callq 0x6b4f
testq %rax, %rax
je 0x5ea6
movq %rax, %r12
movq 0x88ac(%rip), %rdi      # 0xe728
movq %r12, %rsi
callq 0x6da2
movq %r15, %rdi
movq %rax, %rsi
callq 0x734e
movq 0x8892(%rip), %rdi      # 0xe728
movq %r12, %rsi
callq 0x6c0b
movq %rax, %r12
testq %rax, %rax
jne 0x5e75
movq %r15, %rdi
callq 0x730a
testl %eax, %eax
sete %al
testl %ebx, %ebx
sete %cl
orb %al, %cl
jne 0x5efd
decl %ebx
movq %r14, %rdi
callq 0x61f1
movq %rax, %r12
movq %r15, %rdi
callq 0x732b
movq %r14, %rdi
movq %r12, %rsi
movq %rax, %rdx
callq 0x5f93
movq %r15, %rdi
callq 0x73d5
movq %r15, %rdi
callq 0x730a
subl $0x1, %ebx
setb %cl
testl %eax, %eax
je 0x5efd
testb %cl, %cl
je 0x5ebe
movq %r15, %rdi
callq 0x74e0
movq %r14, %rax
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq