// File: millanek[P]evo/process_vcf_stats_functions.cpp
// Function: privateVars_analysis(std::vector<int, std::allocator<int>>&, FilterResult const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long>>, std::allocator<std::vector<unsigned long, std::allocator<unsigned long>>>> const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long>>, std::allocator<std::vector<unsigned long, std::allocator<unsigned long>>>> const&)
void privateVars_analysis(std::vector<int>& privateVarCounts, const FilterResult& result, const std::vector<std::vector<size_t> >& populationsIndices, const std::vector<std::vector<size_t> >& populationsIndicesComplements) {
    for (int i = 0; i < (int)populationsIndices.size(); i++) {
        bool allAlts = true; bool allRefs = true;
        for (int j = 0; j < populationsIndices[i].size(); j++) {
            if (result.counts.individualsWithVariant[populationsIndices[i][j]] != 2)
                allAlts = false;
            if (result.counts.individualsWithVariant[populationsIndices[i][j]] != 0)
                allRefs = false;
            if (!allAlts && !allRefs)
                break;
        }
        if (!allAlts && !allRefs)
            break;
        
        // If all individuals in the population have the same allele (either all alt or all ref)
        // Then we look at the rest of the individuals in the dataset (complement)
        bool privateVar = true;
        if (allAlts) {
            for (int j = 0; j < populationsIndicesComplements[i].size(); j++) {
                if (result.counts.individualsWithVariant[populationsIndicesComplements[i][j]] != 0)
                    privateVar = false;
            }
            //print_vector_stream(populationsIndices[i], std::cerr);
            //print_vector_stream(result.counts.individualsWithVariant, std::cerr);
        }
        if (allRefs) {
            for (int j = 0; j < (int)populationsIndicesComplements[i].size(); j++) {
                if (result.counts.individualsWithVariant[populationsIndicesComplements[i][j]] != 2)
                privateVar = false;
            }
        }
        if (privateVar) {
            privateVarCounts[i]++;
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movl $0x0, -0x24(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0x3c(%rbp)
movq -0x18(%rbp), %rdi
callq 0x9d720
movq %rax, %rcx
movl -0x3c(%rbp), %eax
cmpl %ecx, %eax
jge 0x9c226
movb $0x1, -0x25(%rbp)
movb $0x1, -0x26(%rbp)
movl $0x0, -0x2c(%rbp)
movslq -0x2c(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x18(%rbp), %rdi
movslq -0x24(%rbp), %rsi
callq 0x9d750
movq %rax, %rdi
callq 0x83b90
movq %rax, %rcx
movq -0x48(%rbp), %rax
cmpq %rcx, %rax
jae 0x9c0e5
movq -0x10(%rbp), %rax
addq $0x8, %rax
addq $0x70, %rax
movq %rax, -0x50(%rbp)
movq -0x18(%rbp), %rdi
movslq -0x24(%rbp), %rsi
callq 0x9d750
movq %rax, %rdi
movslq -0x2c(%rbp), %rsi
callq 0x9d770
movq -0x50(%rbp), %rdi
movq (%rax), %rsi
callq 0x48250
cmpl $0x2, (%rax)
je 0x9c089
movb $0x0, -0x25(%rbp)
movq -0x10(%rbp), %rax
addq $0x8, %rax
addq $0x70, %rax
movq %rax, -0x58(%rbp)
movq -0x18(%rbp), %rdi
movslq -0x24(%rbp), %rsi
callq 0x9d750
movq %rax, %rdi
movslq -0x2c(%rbp), %rsi
callq 0x9d770
movq -0x58(%rbp), %rdi
movq (%rax), %rsi
callq 0x48250
cmpl $0x0, (%rax)
je 0x9c0c7
movb $0x0, -0x26(%rbp)
testb $0x1, -0x25(%rbp)
jne 0x9c0d5
testb $0x1, -0x26(%rbp)
jne 0x9c0d5
jmp 0x9c0e5
jmp 0x9c0d7
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x9c01e
testb $0x1, -0x25(%rbp)
jne 0x9c0f6
testb $0x1, -0x26(%rbp)
jne 0x9c0f6
jmp 0x9c226
movb $0x1, -0x2d(%rbp)
testb $0x1, -0x25(%rbp)
je 0x9c17d
movl $0x0, -0x34(%rbp)
movslq -0x34(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x20(%rbp), %rdi
movslq -0x24(%rbp), %rsi
callq 0x9d750
movq %rax, %rdi
callq 0x83b90
movq %rax, %rcx
movq -0x60(%rbp), %rax
cmpq %rcx, %rax
jae 0x9c17b
movq -0x10(%rbp), %rax
addq $0x8, %rax
addq $0x70, %rax
movq %rax, -0x68(%rbp)
movq -0x20(%rbp), %rdi
movslq -0x24(%rbp), %rsi
callq 0x9d750
movq %rax, %rdi
movslq -0x34(%rbp), %rsi
callq 0x9d770
movq -0x68(%rbp), %rdi
movq (%rax), %rsi
callq 0x48250
cmpl $0x0, (%rax)
je 0x9c16e
movb $0x0, -0x2d(%rbp)
jmp 0x9c170
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x9c107
jmp 0x9c17d
testb $0x1, -0x26(%rbp)
je 0x9c1fc
movl $0x0, -0x38(%rbp)
movl -0x38(%rbp), %eax
movl %eax, -0x6c(%rbp)
movq -0x20(%rbp), %rdi
movslq -0x24(%rbp), %rsi
callq 0x9d750
movq %rax, %rdi
callq 0x83b90
movq %rax, %rcx
movl -0x6c(%rbp), %eax
cmpl %ecx, %eax
jge 0x9c1fa
movq -0x10(%rbp), %rax
addq $0x8, %rax
addq $0x70, %rax
movq %rax, -0x78(%rbp)
movq -0x20(%rbp), %rdi
movslq -0x24(%rbp), %rsi
callq 0x9d750
movq %rax, %rdi
movslq -0x38(%rbp), %rsi
callq 0x9d770
movq -0x78(%rbp), %rdi
movq (%rax), %rsi
callq 0x48250
cmpl $0x2, (%rax)
je 0x9c1ed
movb $0x0, -0x2d(%rbp)
jmp 0x9c1ef
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0x9c18a
jmp 0x9c1fc
testb $0x1, -0x2d(%rbp)
je 0x9c216
movq -0x8(%rbp), %rdi
movslq -0x24(%rbp), %rsi
callq 0x4d100
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x9c218
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x9bff2
addq $0x80, %rsp
popq %rbp
retq
nop