// File: rpetit3[P]fastq-scan/fastq-scan.cpp
// Function: main
int main(int argc, char **argv) {
    // Read command line
    float GENOME_SIZE =  1.0;
    int PHRED_OFFSET = 33;
    bool QC_ONLY = false;
    int opt;
    while ((opt = getopt(argc, argv, "g:p:qvh")) >= 0) {
        switch (opt) {
            case 'g': GENOME_SIZE = atof(optarg); break;
            case 'p': PHRED_OFFSET = atoi(optarg); break;
            case 'q': QC_ONLY = true; break;
            case 'v': return version();
            case 'h': return usage();
        }
    }
    if (!(PHRED_OFFSET == 33 || PHRED_OFFSET == 64)) {
        cerr << "Invalid value for -p (" << PHRED_OFFSET << "), only 33 or 64 are valid" << endl;
        return 1;
    } else if (GENOME_SIZE < 0) {
        cerr << "Invalid value for -g (" << GENOME_SIZE << "), value muse be >= 0" << endl;
        return 1;
    }
    
    if (isatty(0)) return usage();

    // Parse FASTQ
    Stats stats;
    stats.init();
    stats.phred = PHRED_OFFSET;
    string name, seq, plus, qual;
    ifstream in("/dev/stdin", ios::in);
    while(true) {
        if(!getline(in, name, '\n')) break;
        if(!getline(in, seq, '\n')) break;
        if(!getline(in, plus, '\n')) break;
        if(!getline(in, qual, '\n')) break;
        stats.read_length.push_back(seq.length());
        stats.read_total++;
        int missing_qual = stats.transform_quality(qual);
        if (missing_qual == 1){
            cerr << "WARNING: Missing quality for a read.\n";
            cerr << name << "\n";
            cerr << seq << "\n";
            cerr << plus << "\n";
            cerr << qual << "\n";
            cerr << "Please fix it to continue.\n";
            exit(50);
        }
    }
    in.close();

    if (stats.read_total > 0) {
        // Determine Stats
        stats.read_stats();
        stats.qual_stats();
        stats.jsonify_stats(GENOME_SIZE, QC_ONLY);
    } else {
        // Empty file, or nothing to parse
        cerr << "Nothing to parse in STDIN, please verify your file is not empty." << endl;
    }
    return 0;
}

// Assembly:
subq $0x468, %rsp            # imm = 0x468
movl $0x0, 0x464(%rsp)
movl %edi, 0x460(%rsp)
movq %rsi, 0x458(%rsp)
movss 0xaabb(%rip), %xmm0     # 0xd004
movss %xmm0, 0x454(%rsp)
movl $0x21, 0x450(%rsp)
movb $0x0, 0x44f(%rsp)
movl 0x460(%rsp), %edi
movq 0x458(%rsp), %rsi
leaq 0xab13(%rip), %rdx      # 0xd08e
callq 0x2050
movl %eax, 0x448(%rsp)
cmpl $0x0, %eax
jl 0x2628
movl 0x448(%rsp), %eax
addl $-0x67, %eax
movl %eax, %ecx
movq %rcx, 0x88(%rsp)
subl $0xf, %eax
ja 0x2623
movq 0x88(%rsp), %rax
leaq 0xaa60(%rip), %rcx      # 0xd018
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0xf9f0(%rip), %rax      # 0x11fb8
movq (%rax), %rdi
callq 0x2220
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x454(%rsp)
jmp 0x2623
movq 0xf9d2(%rip), %rax      # 0x11fb8
movq (%rax), %rdi
callq 0x2280
movl %eax, 0x450(%rsp)
jmp 0x2623
movb $0x1, 0x44f(%rsp)
jmp 0x2623
callq 0x2c10
movl %eax, 0x464(%rsp)
jmp 0x2bf0
callq 0x2c50
movl %eax, 0x464(%rsp)
jmp 0x2bf0
jmp 0x2565
cmpl $0x21, 0x450(%rsp)
je 0x268c
cmpl $0x40, 0x450(%rsp)
je 0x268c
movq 0xf9ad(%rip), %rdi      # 0x11ff0
leaq 0xaa4c(%rip), %rsi      # 0xd096
callq 0x2180
movq %rax, %rdi
movl 0x450(%rsp), %esi
callq 0x22b0
movq %rax, %rdi
leaq 0xaa45(%rip), %rsi      # 0xd0ad
callq 0x2180
movq %rax, %rdi
movq 0xf939(%rip), %rsi      # 0x11fb0
callq 0x21b0
movl $0x1, 0x464(%rsp)
jmp 0x2bf0
xorps %xmm0, %xmm0
ucomiss 0x454(%rsp), %xmm0
jbe 0x26eb
movq 0xf950(%rip), %rdi      # 0x11ff0
leaq 0xaa21(%rip), %rsi      # 0xd0c8
callq 0x2180
movq %rax, %rdi
movss 0x454(%rsp), %xmm0
callq 0x2110
movq %rax, %rdi
leaq 0xaa18(%rip), %rsi      # 0xd0df
callq 0x2180
movq %rax, %rdi
movq 0xf8da(%rip), %rsi      # 0x11fb0
callq 0x21b0
movl $0x1, 0x464(%rsp)
jmp 0x2bf0
jmp 0x26ed
xorl %edi, %edi
callq 0x22c0
cmpl $0x0, %eax
je 0x270a
callq 0x2c50
movl %eax, 0x464(%rsp)
jmp 0x2bf0
leaq 0x350(%rsp), %rdi
movq %rdi, 0x80(%rsp)
callq 0x2e60
movq 0x80(%rsp), %rdi
callq 0x2ec0
jmp 0x272e
movl 0x450(%rsp), %eax
movl %eax, 0x408(%rsp)
leaq 0x320(%rsp), %rdi
callq 0x2240
leaq 0x300(%rsp), %rdi
callq 0x2240
leaq 0x2e0(%rsp), %rdi
callq 0x2240
leaq 0x2c0(%rsp), %rdi
callq 0x2240
leaq 0xa97e(%rip), %rsi      # 0xd0f5
leaq 0xb8(%rsp), %rdi
movl $0x8, %edx
callq 0x2310
jmp 0x278b
jmp 0x278d
jmp 0x278f
leaq 0xb8(%rsp), %rdi
leaq 0x320(%rsp), %rsi
movl $0xa, %edx
callq 0x2320
movq %rax, 0x78(%rsp)
jmp 0x27b0
movq 0x78(%rsp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x20d0
movb %al, 0x77(%rsp)
jmp 0x27ca
movb 0x77(%rsp), %al
testb $0x1, %al
jne 0x27d4
jmp 0x2824
jmp 0x2ab9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x348(%rsp)
movl %eax, 0x344(%rsp)
jmp 0x2be1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x348(%rsp)
movl %eax, 0x344(%rsp)
jmp 0x2bad
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x348(%rsp)
movl %eax, 0x344(%rsp)
jmp 0x2ba0
leaq 0xb8(%rsp), %rdi
leaq 0x300(%rsp), %rsi
movl $0xa, %edx
callq 0x2320
movq %rax, 0x68(%rsp)
jmp 0x2845
movq 0x68(%rsp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x20d0
movb %al, 0x67(%rsp)
jmp 0x285f
movb 0x67(%rsp), %al
testb $0x1, %al
jne 0x2869
jmp 0x286e
jmp 0x2ab9
leaq 0xb8(%rsp), %rdi
leaq 0x2e0(%rsp), %rsi
movl $0xa, %edx
callq 0x2320
movq %rax, 0x58(%rsp)
jmp 0x288f
movq 0x58(%rsp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x20d0
movb %al, 0x57(%rsp)
jmp 0x28a9
movb 0x57(%rsp), %al
testb $0x1, %al
jne 0x28b3
jmp 0x28b8
jmp 0x2ab9
leaq 0xb8(%rsp), %rdi
leaq 0x2c0(%rsp), %rsi
movl $0xa, %edx
callq 0x2320
movq %rax, 0x48(%rsp)
jmp 0x28d9
movq 0x48(%rsp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x20d0
movb %al, 0x47(%rsp)
jmp 0x28f3
movb 0x47(%rsp), %al
testb $0x1, %al
jne 0x28fd
jmp 0x2902
jmp 0x2ab9
leaq 0x358(%rsp), %rax
movq %rax, 0x38(%rsp)
leaq 0x300(%rsp), %rdi
callq 0x2260
movq 0x38(%rsp), %rdi
movl %eax, 0xb4(%rsp)
leaq 0xb4(%rsp), %rsi
callq 0x2f60
jmp 0x2937
movq 0x388(%rsp), %rax
incq %rax
movq %rax, 0x388(%rsp)
leaq 0x90(%rsp), %rdi
leaq 0x2c0(%rsp), %rsi
callq 0x20b0
jmp 0x2961
leaq 0x350(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0x2f90
movl %eax, 0x34(%rsp)
jmp 0x297c
leaq 0x90(%rsp), %rdi
callq 0x2368
movl 0x34(%rsp), %eax
movl %eax, 0xb0(%rsp)
cmpl $0x1, 0xb0(%rsp)
jne 0x2ab4
movq 0xf647(%rip), %rdi      # 0x11ff0
leaq 0xa750(%rip), %rsi      # 0xd100
callq 0x2180
jmp 0x29b7
movq 0xf632(%rip), %rdi      # 0x11ff0
leaq 0x320(%rsp), %rsi
callq 0x2170
movq %rax, 0x28(%rsp)
jmp 0x29d2
movq 0x28(%rsp), %rdi
leaq 0xa746(%rip), %rsi      # 0xd124
callq 0x2180
jmp 0x29e5
movq 0xf604(%rip), %rdi      # 0x11ff0
leaq 0x300(%rsp), %rsi
callq 0x2170
movq %rax, 0x20(%rsp)
jmp 0x2a00
movq 0x20(%rsp), %rdi
leaq 0xa718(%rip), %rsi      # 0xd124
callq 0x2180
jmp 0x2a13
movq 0xf5d6(%rip), %rdi      # 0x11ff0
leaq 0x2e0(%rsp), %rsi
callq 0x2170
movq %rax, 0x18(%rsp)
jmp 0x2a2e
movq 0x18(%rsp), %rdi
leaq 0xa6ea(%rip), %rsi      # 0xd124
callq 0x2180
jmp 0x2a41
movq 0xf5a8(%rip), %rdi      # 0x11ff0
leaq 0x2c0(%rsp), %rsi
callq 0x2170
movq %rax, 0x10(%rsp)
jmp 0x2a5c
movq 0x10(%rsp), %rdi
leaq 0xa6bc(%rip), %rsi      # 0xd124
callq 0x2180
jmp 0x2a6f
movq 0xf57a(%rip), %rdi      # 0x11ff0
leaq 0xa6a9(%rip), %rsi      # 0xd126
callq 0x2180
jmp 0x2a84
movl $0x32, %edi
callq 0x2200
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x348(%rsp)
movl %eax, 0x344(%rsp)
leaq 0x90(%rsp), %rdi
callq 0x2368
jmp 0x2ba0
jmp 0x278d
leaq 0xb8(%rsp), %rdi
callq 0x2040
jmp 0x2ac8
cmpq $0x0, 0x388(%rsp)
jbe 0x2b16
leaq 0x350(%rsp), %rdi
callq 0x3120
jmp 0x2ae2
leaq 0x350(%rsp), %rdi
callq 0x3490
jmp 0x2af1
movss 0x454(%rsp), %xmm0
movzbl 0x44f(%rsp), %esi
andl $0x1, %esi
leaq 0x350(%rsp), %rdi
callq 0x37e0
jmp 0x2b14
jmp 0x2b45
movq 0xf4d3(%rip), %rdi      # 0x11ff0
leaq 0xa61e(%rip), %rsi      # 0xd142
callq 0x2180
movq %rax, 0x8(%rsp)
jmp 0x2b30
movq 0x8(%rsp), %rdi
movq 0xf474(%rip), %rsi      # 0x11fb0
callq 0x21b0
jmp 0x2b43
jmp 0x2b45
movl $0x0, 0x464(%rsp)
leaq 0xb8(%rsp), %rdi
callq 0x2070
leaq 0x2c0(%rsp), %rdi
callq 0x2368
leaq 0x2e0(%rsp), %rdi
callq 0x2368
leaq 0x300(%rsp), %rdi
callq 0x2368
leaq 0x320(%rsp), %rdi
callq 0x2368
leaq 0x350(%rsp), %rdi
callq 0x49c0
jmp 0x2bf0
leaq 0xb8(%rsp), %rdi
callq 0x2070
leaq 0x2c0(%rsp), %rdi
callq 0x2368
leaq 0x2e0(%rsp), %rdi
callq 0x2368
leaq 0x300(%rsp), %rdi
callq 0x2368
leaq 0x320(%rsp), %rdi
callq 0x2368
leaq 0x350(%rsp), %rdi
callq 0x49c0
jmp 0x2bff
movl 0x464(%rsp), %eax
addq $0x468, %rsp            # imm = 0x468
retq
movq 0x348(%rsp), %rdi
callq 0x22e0
nopl (%rax)