// File: zeeev[P]DASVC/bamtools/src/toolkit/bamtools_count.cpp
// Function: BamTools::CountTool::CountToolPrivate::Run()
bool CountTool::CountToolPrivate::Run(void) {

    // set to default input if none provided
    if ( !m_settings->HasInput && !m_settings->HasInputFilelist )
        m_settings->InputFiles.push_back(Options::StandardIn());

    // add files in the filelist to the input file list
    if ( m_settings->HasInputFilelist ) {

        ifstream filelist(m_settings->InputFilelist.c_str(), ios::in);
        if ( !filelist.is_open() ) {
            cerr << "bamtools count ERROR: could not open input BAM file list... Aborting." << endl;
            return false;
        }

        string line;
        while ( getline(filelist, line) )
            m_settings->InputFiles.push_back(line);
    }

    // open reader without index
    BamMultiReader reader;
    if ( !reader.Open(m_settings->InputFiles) ) {
        cerr << "bamtools count ERROR: could not open input BAM file(s)... Aborting." << endl;
        return false;
    }

    // alignment counter
    BamAlignment al;
    int alignmentCount(0);

    // if no region specified, count entire file
    if ( !m_settings->HasRegion ) {
        while ( reader.GetNextAlignmentCore(al) )
            ++alignmentCount;
    }

    // otherwise attempt to use region as constraint
    else {

        // if region string parses OK
        BamRegion region;
        if ( Utilities::ParseRegionString(m_settings->Region, reader, region) ) {

            // attempt to find index files
            reader.LocateIndexes();

            // if index data available for all BAM files, we can use SetRegion
            if ( reader.HasIndexes() ) {

                // attempt to set region on reader
                if ( !reader.SetRegion(region.LeftRefID, region.LeftPosition, region.RightRefID, region.RightPosition) ) {
                    cerr << "bamtools count ERROR: set region failed. Check that REGION describes a valid range" << endl;
                    reader.Close();
                    return false;
                }

                // everything checks out, just iterate through specified region, counting alignments
                while ( reader.GetNextAlignmentCore(al) )
                    ++alignmentCount;
            }

            // no index data available, we have to iterate through until we
            // find overlapping alignments
            else {
                while ( reader.GetNextAlignmentCore(al) ) {
                    if ( (al.RefID >= region.LeftRefID)  && ( (al.Position + al.Length) >= region.LeftPosition ) &&
                          (al.RefID <= region.RightRefID) && ( al.Position <= region.RightPosition) )
                    {
                        ++alignmentCount;
                    }
                }
            }
        }

        // error parsing REGION string
        else {
            cerr << "bamtools count ERROR: could not parse REGION - " << m_settings->Region << endl;
            cerr << "Check that REGION is in valid format (see documentation) and that the coordinates are valid"
                 << endl;
            reader.Close();
            return false;
        }
    }

    // print results
    cout << alignmentCount << endl;

    // clean up & exit
    reader.Close();
    return true;
}

// Assembly:
subq $0x458, %rsp            # imm = 0x458
movq %rdi, 0x448(%rsp)
movq 0x448(%rsp), %rax
movq %rax, 0x80(%rsp)
movq (%rax), %rax
testb $0x1, (%rax)
jne 0x9778e
movq 0x80(%rsp), %rax
movq (%rax), %rax
testb $0x1, 0x1(%rax)
jne 0x9778e
movq 0x80(%rsp), %rax
movq (%rax), %rax
addq $0x8, %rax
movq %rax, 0x78(%rsp)
callq 0x10f280
movq 0x78(%rsp), %rdi
movq %rax, %rsi
callq 0x91220
movq 0x80(%rsp), %rax
movq (%rax), %rax
testb $0x1, 0x1(%rax)
je 0x97930
movq 0x80(%rsp), %rax
movq (%rax), %rdi
addq $0x20, %rdi
callq 0x86320
movq %rax, %rsi
leaq 0x240(%rsp), %rdi
movq %rdi, 0x68(%rsp)
movl $0x8, %edx
callq 0x86e30
movq 0x68(%rsp), %rdi
callq 0x86c10
movb %al, 0x77(%rsp)
jmp 0x977e1
movb 0x77(%rsp), %al
testb $0x1, %al
jne 0x97849
jmp 0x977eb
movq 0xcd7ee(%rip), %rdi     # 0x164fe0
leaq 0x971a5(%rip), %rsi     # 0x12e99e
callq 0x86700
movq %rax, 0x60(%rsp)
jmp 0x97805
movq 0x60(%rsp), %rdi
movq 0xcd75f(%rip), %rsi     # 0x164f70
callq 0x86770
jmp 0x97818
movb $0x0, 0x457(%rsp)
movl $0x1, 0x230(%rsp)
jmp 0x978f9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0x9791c
leaq 0x210(%rsp), %rdi
callq 0x86a30
jmp 0x97858
jmp 0x9785a
leaq 0x240(%rsp), %rdi
leaq 0x210(%rsp), %rsi
callq 0x86140
movq %rax, 0x58(%rsp)
jmp 0x97876
movq 0x58(%rsp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x86b60
movq %rax, 0x50(%rsp)
jmp 0x97891
movq 0x50(%rsp), %rax
cmpq $0x0, %rax
je 0x978df
movq 0x80(%rsp), %rax
movq (%rax), %rdi
addq $0x8, %rdi
leaq 0x210(%rsp), %rsi
callq 0x91220
jmp 0x978ba
jmp 0x9785a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
leaq 0x210(%rsp), %rdi
callq 0x86f68
jmp 0x9791a
leaq 0x210(%rsp), %rdi
callq 0x86f68
jmp 0x978ee
movl $0x0, 0x230(%rsp)
leaq 0x240(%rsp), %rdi
callq 0x861c0
movl 0x230(%rsp), %eax
testl %eax, %eax
je 0x97918
jmp 0x97913
jmp 0x97da5
jmp 0x97930
jmp 0x9791c
leaq 0x240(%rsp), %rdi
callq 0x861c0
jmp 0x9792b
jmp 0x97db6
leaq 0x208(%rsp), %rdi
movq %rdi, 0x40(%rsp)
callq 0x86db0
movq 0x80(%rsp), %rax
movq 0x40(%rsp), %rdi
movq (%rax), %rsi
addq $0x8, %rsi
callq 0x864a0
movb %al, 0x4f(%rsp)
jmp 0x97961
movb 0x4f(%rsp), %al
testb $0x1, %al
jne 0x979c9
jmp 0x9796b
movq 0xcd66e(%rip), %rdi     # 0x164fe0
leaq 0x9706b(%rip), %rsi     # 0x12e9e4
callq 0x86700
movq %rax, 0x38(%rsp)
jmp 0x97985
movq 0x38(%rsp), %rdi
movq 0xcd5df(%rip), %rsi     # 0x164f70
callq 0x86770
jmp 0x97998
movb $0x0, 0x457(%rsp)
movl $0x1, 0x230(%rsp)
jmp 0x97d85
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0x97d94
leaq 0xb0(%rsp), %rdi
callq 0x86260
jmp 0x979d8
movq 0x80(%rsp), %rax
movl $0x0, 0xac(%rsp)
movq (%rax), %rax
testb $0x1, 0x2(%rax)
jne 0x97a59
jmp 0x979f6
leaq 0x208(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0x86190
movb %al, 0x37(%rsp)
jmp 0x97a11
movb 0x37(%rsp), %al
testb $0x1, %al
jne 0x97a1b
jmp 0x97a54
movl 0xac(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xac(%rsp)
jmp 0x979f6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
leaq 0xb0(%rsp), %rdi
callq 0x86b30
jmp 0x97d83
jmp 0x97d25
movl $0xffffffff, 0x98(%rsp) # imm = 0xFFFFFFFF
movl $0xffffffff, 0x94(%rsp) # imm = 0xFFFFFFFF
movl $0xffffffff, 0x90(%rsp) # imm = 0xFFFFFFFF
movl $0xffffffff, 0x8c(%rsp) # imm = 0xFFFFFFFF
leaq 0x9c(%rsp), %rdi
leaq 0x98(%rsp), %rsi
leaq 0x94(%rsp), %rdx
leaq 0x90(%rsp), %rcx
leaq 0x8c(%rsp), %r8
callq 0x915e0
jmp 0x97ab4
movq 0x80(%rsp), %rax
movq (%rax), %rdi
addq $0x40, %rdi
leaq 0x208(%rsp), %rsi
leaq 0x9c(%rsp), %rdx
callq 0x115500
movb %al, 0x36(%rsp)
jmp 0x97ade
movb 0x36(%rsp), %al
testb $0x1, %al
jne 0x97aeb
jmp 0x97c85
movl $0x1, 0x88(%rsp)
leaq 0x208(%rsp), %rdi
leaq 0x88(%rsp), %rsi
callq 0x86950
jmp 0x97b0d
leaq 0x208(%rsp), %rdi
callq 0x864c0
movb %al, 0x35(%rsp)
jmp 0x97b20
movb 0x35(%rsp), %al
testb $0x1, %al
jne 0x97b2d
jmp 0x97bfd
leaq 0xa0(%rsp), %rdx
leaq 0xa4(%rsp), %rcx
leaq 0xa8(%rsp), %r8
leaq 0x208(%rsp), %rdi
leaq 0x9c(%rsp), %rsi
callq 0x86cf0
movb %al, 0x34(%rsp)
jmp 0x97b60
movb 0x34(%rsp), %al
testb $0x1, %al
jne 0x97bbe
jmp 0x97b6a
movq 0xcd46f(%rip), %rdi     # 0x164fe0
leaq 0x96eb0(%rip), %rsi     # 0x12ea28
callq 0x86700
movq %rax, 0x28(%rsp)
jmp 0x97b84
movq 0x28(%rsp), %rdi
movq 0xcd3e0(%rip), %rsi     # 0x164f70
callq 0x86770
jmp 0x97b97
leaq 0x208(%rsp), %rdi
callq 0x861e0
jmp 0x97ba6
movb $0x0, 0x457(%rsp)
movl $0x1, 0x230(%rsp)
jmp 0x97d72
jmp 0x97bc0
leaq 0x208(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0x86190
movb %al, 0x27(%rsp)
jmp 0x97bdb
movb 0x27(%rsp), %al
testb $0x1, %al
jne 0x97be5
jmp 0x97bf8
movl 0xac(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xac(%rsp)
jmp 0x97bc0
jmp 0x97c80
jmp 0x97bff
leaq 0x208(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0x86190
movb %al, 0x26(%rsp)
jmp 0x97c1a
movb 0x26(%rsp), %al
testb $0x1, %al
jne 0x97c24
jmp 0x97c7e
movl 0x158(%rsp), %eax
cmpl 0x9c(%rsp), %eax
jl 0x97c7c
movl 0x15c(%rsp), %eax
addl 0xd0(%rsp), %eax
cmpl 0xa0(%rsp), %eax
jl 0x97c7c
movl 0x158(%rsp), %eax
cmpl 0xa4(%rsp), %eax
jg 0x97c7c
movl 0x15c(%rsp), %eax
cmpl 0xa8(%rsp), %eax
jg 0x97c7c
movl 0xac(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xac(%rsp)
jmp 0x97bff
jmp 0x97c80
jmp 0x97d23
movq 0xcd354(%rip), %rdi     # 0x164fe0
leaq 0x96de8(%rip), %rsi     # 0x12ea7b
callq 0x86700
movq %rax, 0x18(%rsp)
jmp 0x97c9f
movq 0x18(%rsp), %rdi
movq 0x80(%rsp), %rax
movq (%rax), %rsi
addq $0x40, %rsi
callq 0x86640
movq %rax, 0x10(%rsp)
jmp 0x97cbf
movq 0x10(%rsp), %rdi
movq 0xcd2a5(%rip), %rsi     # 0x164f70
callq 0x86770
jmp 0x97cd2
movq 0xcd307(%rip), %rdi     # 0x164fe0
leaq 0x96674(%rip), %rsi     # 0x12e354
callq 0x86700
movq %rax, 0x8(%rsp)
jmp 0x97cec
movq 0x8(%rsp), %rdi
movq 0xcd278(%rip), %rsi     # 0x164f70
callq 0x86770
jmp 0x97cff
leaq 0x208(%rsp), %rdi
callq 0x861e0
jmp 0x97d0e
movb $0x0, 0x457(%rsp)
movl $0x1, 0x230(%rsp)
jmp 0x97d72
jmp 0x97d25
movl 0xac(%rsp), %esi
movq 0xcd265(%rip), %rdi     # 0x164f98
callq 0x86d40
movq %rax, (%rsp)
jmp 0x97d3e
movq (%rsp), %rdi
movq 0xcd227(%rip), %rsi     # 0x164f70
callq 0x86770
jmp 0x97d50
leaq 0x208(%rsp), %rdi
callq 0x861e0
jmp 0x97d5f
movb $0x1, 0x457(%rsp)
movl $0x1, 0x230(%rsp)
leaq 0xb0(%rsp), %rdi
callq 0x86b30
jmp 0x97d81
jmp 0x97d85
jmp 0x97d94
leaq 0x208(%rsp), %rdi
callq 0x86150
jmp 0x97da5
leaq 0x208(%rsp), %rdi
callq 0x86150
jmp 0x97da3
jmp 0x97db6
movb 0x457(%rsp), %al
andb $0x1, %al
addq $0x458, %rsp            # imm = 0x458
retq
movq 0x238(%rsp), %rdi
callq 0x86d80
movq %rax, %rdi
callq 0x91290
nopl (%rax,%rax)