// File: /workspace/github_c_makefile_star2_O0/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 %rbp
movq %rsp, %rbp
subq $0xd0, %rsp
movl %edi, -0xc(%rbp)
movq %rsi, -0x18(%rbp)
movq 0x8297(%rip), %rdi      # 0xf720
movq -0x18(%rbp), %rsi
callq 0x86d5
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x76e0
cmpq $0x0, -0x18(%rbp)
je 0x76db
leaq -0x1b63(%rip), %rdi     # 0x5950
xorl %eax, %eax
movl %eax, %esi
movq 0x7b02(%rip), %rdx      # 0xefc0
callq 0x7c0c
movq %rax, 0x8236(%rip)      # 0xf700
movq 0x822f(%rip), %rdi      # 0xf700
leaq 0x1302(%rip), %rsi      # 0x87da
callq 0x87bb
movq 0x823c(%rip), %rdi      # 0xf720
movq -0x20(%rbp), %rsi
callq 0x86bb
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
callq 0x9ae6
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x7563
movq -0x28(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x9b90
movq %rax, -0x38(%rbp)
movq 0x81e3(%rip), %rax      # 0xf700
movq %rax, -0x90(%rbp)
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x88(%rbp)
xorl %edi, %edi
callq 0x5bc0
movq -0x90(%rbp), %rdi
movq -0x88(%rbp), %rsi
movq %rax, %rdx
callq 0x7ee6
movq -0x28(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x9b5c
movq %rax, -0x30(%rbp)
jmp 0x74fe
movq -0x28(%rbp), %rdi
callq 0x9ae6
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
je 0x75be
movq -0x28(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x9b90
movq %rax, -0x48(%rbp)
movq 0x8171(%rip), %rdi      # 0xf700
movq -0x48(%rbp), %rax
movq 0x10(%rax), %rsi
callq 0x826d
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movq -0x28(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x9b5c
movq %rax, -0x40(%rbp)
jmp 0x7570
leaq -0x1aa5(%rip), %rdi     # 0x5b20
xorl %eax, %eax
movl %eax, %edx
movq %rdx, %rsi
callq 0x8b70
movq %rax, -0x58(%rbp)
movq 0x8124(%rip), %rdi      # 0xf700
callq 0x844f
movq %rax, -0x60(%rbp)
cmpq $0x0, -0x60(%rbp)
je 0x762c
movq -0x58(%rbp), %rax
movq %rax, -0x98(%rbp)
movq 0x8102(%rip), %rdi      # 0xf700
movq -0x60(%rbp), %rsi
callq 0x86a2
movq -0x98(%rbp), %rdi
movq %rax, %rsi
callq 0x8c4e
movq 0x80e3(%rip), %rdi      # 0xf700
movq -0x60(%rbp), %rsi
callq 0x850b
movq %rax, -0x60(%rbp)
jmp 0x75e5
xorl %eax, %eax
movl %eax, %edi
callq 0x7812
movq %rax, -0x68(%rbp)
movq -0x58(%rbp), %rdi
callq 0x8c0a
movl %eax, %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
movb %al, -0x99(%rbp)
je 0x7668
movl -0xc(%rbp), %eax
movl %eax, %ecx
addl $-0x1, %ecx
movl %ecx, -0xc(%rbp)
cmpl $0x0, %eax
setne %al
movb %al, -0x99(%rbp)
movb -0x99(%rbp), %al
testb $0x1, %al
jne 0x7674
jmp 0x76b9
movq -0x68(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0x68(%rbp), %rdi
callq 0x7af1
movq %rax, -0xa8(%rbp)
movq -0x58(%rbp), %rdi
callq 0x8c2b
movq -0xb0(%rbp), %rdi
movq -0xa8(%rbp), %rsi
movq %rax, %rdx
callq 0x7893
movq -0x58(%rbp), %rdi
callq 0x8cd5
jmp 0x7639
movq -0x58(%rbp), %rdi
callq 0x8de0
movq 0x8037(%rip), %rdi      # 0xf700
callq 0x830c
movq -0x68(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x7805
jmp 0x77fd
cmpq $0x0, -0x18(%rbp)
jne 0x77fb
xorl %eax, %eax
movl %eax, %edi
callq 0x7812
movq %rax, -0x70(%rbp)
leaq -0x1b8f(%rip), %rdi     # 0x5b70
xorl %eax, %eax
movl %eax, %edx
movq %rdx, %rsi
callq 0x8b70
movq %rax, -0x78(%rbp)
movq 0x7ff2(%rip), %rdi      # 0xf708
callq 0x844f
movq %rax, -0x80(%rbp)
cmpq $0x0, -0x80(%rbp)
je 0x7766
movq -0x78(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq 0x7fd0(%rip), %rdi      # 0xf708
movq -0x80(%rbp), %rsi
callq 0x86a2
movq -0xb8(%rbp), %rdi
movq %rax, %rsi
callq 0x8c4e
movq 0x7fb1(%rip), %rdi      # 0xf708
movq -0x80(%rbp), %rsi
callq 0x850b
movq %rax, -0x80(%rbp)
jmp 0x771f
jmp 0x7768
movq -0x78(%rbp), %rdi
callq 0x8c0a
movl %eax, %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
movb %al, -0xb9(%rbp)
je 0x7797
movl -0xc(%rbp), %eax
movl %eax, %ecx
addl $-0x1, %ecx
movl %ecx, -0xc(%rbp)
cmpl $0x0, %eax
setne %al
movb %al, -0xb9(%rbp)
movb -0xb9(%rbp), %al
testb $0x1, %al
jne 0x77a3
jmp 0x77e8
movq -0x70(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq -0x70(%rbp), %rdi
callq 0x7af1
movq %rax, -0xc8(%rbp)
movq -0x78(%rbp), %rdi
callq 0x8c2b
movq -0xd0(%rbp), %rdi
movq -0xc8(%rbp), %rsi
movq %rax, %rdx
callq 0x7893
movq -0x78(%rbp), %rdi
callq 0x8cd5
jmp 0x7768
movq -0x78(%rbp), %rdi
callq 0x8de0
movq -0x70(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x7805
jmp 0x77fd
movq $0x0, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xd0, %rsp
popq %rbp
retq