// File: /workspace/github_c_makefile_star2_O2/c-zhou[P]oatk/run_hmmannot.c
// Function: annot_worker_pipeline
static void *annot_worker_pipeline(void *shared, int step, void *in)
{
    annot_pipeline_t *p = (annot_pipeline_t *) shared;
    if (step == 0) { // read sequence data into bacthes        
        annot_step_t *annot_s;
        MYCALLOC(annot_s, 1);
        MYMALLOC(annot_s->temp_in, p->max_batch_num);
        MYMALLOC(annot_s->temp_out, p->max_batch_num);

        kstream_t *ks = p->ks;
        kstring_t *s = p->s;
        int dret, ret, is_fa, is_fq, is_gfa;
        uint32_t batch_size, batch_num, n_seq, l_seq;
        FILE *fo;
        char file_template[strlen(p->tmpdir) + 16];

        is_fa = is_fq = is_gfa = 0;
        batch_size = batch_num = 0;
        fo = 0;
        n_seq = l_seq = 0;

        // need the file names only and the file descriptors have already been closed
        annot_s->temp_in[batch_num]  = make_tempfile(p->tmpdir, file_template, ".fa");
        annot_s->temp_out[batch_num] = make_tempfile(p->tmpdir, file_template, ".out");
        
        fo = fopen(annot_s->temp_in[batch_num], "w");
        ++batch_num;

        while (s->l || ks_getuntil(ks, KS_SEP_LINE, s, &dret) >= 0) {
            if (s->l == 0) // empty line
                continue;
            
            if (batch_size >= p->max_batch_size && (is_gfa || (is_fa && s->s[0] == '>') || (is_fq && s->s[0] == '@'))) {
                fclose(fo);
                fo = 0;
                l_seq += batch_size;

                if (batch_num >= p->max_batch_num) {
                    break;
                } else {
                    // make a new batch
                    // need the file names only and the file descriptors have already been closed
                    annot_s->temp_in[batch_num]  = make_tempfile(p->tmpdir, file_template, ".fa");
                    annot_s->temp_out[batch_num] = make_tempfile(p->tmpdir, file_template, ".out");
                    fo = fopen(annot_s->temp_in[batch_num], "w");
                    ++batch_num;
                    batch_size = 0;
                }
            }

            ret = 0; 
            if (!is_gfa && s->s[0] == '>') { // FASTA header
                is_fa = 1;
                // parse header
                ret = parse_fheader(s->s);
                if (!ret)
                    fprintf(fo, "%s\n", s->s);
                ++n_seq;
            } else if (!is_gfa && s->s[0] == '@') { // FASTQ header
                is_fq = 1;
                // parse and write header
                ret = parse_fheader(s->s);
                if (!ret)
                    fprintf(fo, ">%s\n", s->s + 1);
                // parse sequence
                if(ks_getuntil(ks, KS_SEP_LINE, s, &dret) < 0)
                    ret = 2;
                if (!ret) {
                    fprintf(fo, "%s\n", s->s);
                    batch_size += s->l;
                }

                // skip quality score lines
                if (ks_getuntil(ks, KS_SEP_LINE, s, &dret) < 0 ||
                        ks_getuntil(ks, KS_SEP_LINE, s, &dret) < 0)
                    ret = 3;
                ++n_seq;
            } else if (is_fa) { // FASTA sequence line
                fprintf(fo, "%s\n", s->s);
                batch_size += s->l;
            } else {
                is_gfa = 1;
                if (s->s[0] == 'S') {
                    char *seg, *seq;
                    seg = seq = NULL;
                    ret = parse_gseq(s->s, &seg, &seq);
                    if (!ret) {
                        fprintf(fo, ">%s\n", seg);
                        fprintf(fo, "%s\n", seq);
                        batch_size += strlen(seq);
                    }
                    ++n_seq;
                }
            }

            if (ret) {
                fprintf(stderr, "[E::%s] failed to parse %s file (error code: %d)\n", __func__, is_fa? "FASTA" : (is_fq? "FASTQ" : "GFA"), ret);
                exit(EXIT_FAILURE);
            }

            s->l = 0;
        }

        if (fo) {
            fclose(fo);
            l_seq += batch_size;
            if (batch_size == 0) {
                --batch_num;
                remove(annot_s->temp_in[batch_num]);
                remove(annot_s->temp_out[batch_num]);
                free(annot_s->temp_in[batch_num]);
                free(annot_s->temp_out[batch_num]);
            }
        }

        assert(is_fa + is_fq + is_gfa <= 1);

        if (batch_num == 0) {
            free(annot_s->temp_in);
            free(annot_s->temp_out);
            free(annot_s);
        } else {
            annot_s->batch_num = batch_num;
            annot_s->shared = p;
            fprintf(stderr, "[M::%s] %u sequences (%u bp) loaded in %u batc%s\n", __func__, n_seq, l_seq, batch_num, batch_num > 1? "hes" : "h");
            return annot_s;
        }
    } else if (step == 1) { // do nhmmscan annotation
        kt_for(p->n_threads, annot_worker_for, in, ((annot_step_t*)in)->batch_num);
        return in;
    } else if (step == 2) { // parse nhmmscan output
        annot_step_t *annot_s = (annot_step_t *) in;
        int i;
        FILE *fp;
        char c;

        for (i = 0; i < annot_s->batch_num; ++i) {
            fp = fopen(annot_s->temp_out[i], "r");
            while ((c = fgetc(fp)) != EOF)
                fputc(c, p->fo);
            fclose(fp);

            remove(annot_s->temp_in[i]);
            remove(annot_s->temp_out[i]);
            free(annot_s->temp_in[i]);
            free(annot_s->temp_out[i]);
        }
        free(annot_s->temp_in);
        free(annot_s->temp_out);
        free(annot_s);
    }

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rdi, %r14
testl %esi, %esi
je 0x27eb
movq %rdx, %rbx
cmpl $0x1, %esi
je 0x27cf
cmpl $0x2, %esi
jne 0x2c96
xorl %r13d, %r13d
leaq 0x3de9(%rip), %r15      # 0x6532
movslq 0x8(%rbx), %rax
cmpq %rax, %r13
jge 0x2bda
movq 0x18(%rbx), %rax
movq (%rax,%r13,8), %rdi
movq %r15, %rsi
callq 0x2310
movq %rax, %r12
movq %r12, %rdi
callq 0x21a0
shll $0x18, %eax
cmpl $0xff000000, %eax       # imm = 0xFF000000
je 0x278b
sarl $0x18, %eax
movq 0x28(%r14), %rsi
movl %eax, %edi
callq 0x21c0
jmp 0x2769
movq %r12, %rdi
callq 0x2110
movq 0x10(%rbx), %rax
movq (%rax,%r13,8), %rdi
callq 0x2080
movq 0x18(%rbx), %rax
movq (%rax,%r13,8), %rdi
callq 0x2080
movq 0x10(%rbx), %rax
movq (%rax,%r13,8), %rdi
callq 0x2050
movq 0x18(%rbx), %rax
movq (%rax,%r13,8), %rdi
callq 0x2050
incq %r13
jmp 0x2749
movl 0x38(%r14), %edi
movslq 0x8(%rbx), %rcx
leaq 0x1048(%rip), %rsi      # 0x3826
movq %rbx, %rdx
callq 0x55c8
jmp 0x2c98
pushq $0x1
popq %rdi
pushq $0x20
popq %rsi
callq 0x21f0
movq %rax, %rbx
movl 0x4(%r14), %r15d
shlq $0x3, %r15
movq %r15, %rdi
callq 0x2280
movq %rax, %r13
movq %rax, 0x10(%rbx)
movq %r15, %rdi
callq 0x2280
movq %rax, -0x38(%rbp)
movq %rax, 0x18(%rbx)
movq 0x18(%r14), %rax
movq %rax, -0x68(%rbp)
movq 0x20(%r14), %r15
movq 0x30(%r14), %rdi
callq 0x2130
movq %rsp, -0x70(%rbp)
movq %rsp, %r12
addq $0x1f, %rax
andq $-0x10, %rax
subq %rax, %r12
movq %r12, %rsp
movq 0x30(%r14), %rdi
leaq 0x3b7d(%rip), %rdx      # 0x63d2
movq %r12, %rsi
callq 0x4d5b
movq %rax, (%r13)
movq 0x30(%r14), %rdi
leaq 0x3b6a(%rip), %rdx      # 0x63d6
movq %r12, -0x78(%rbp)
movq %r12, %rsi
callq 0x4d5b
movq -0x38(%rbp), %rcx
movq %rax, (%rcx)
movq (%r13), %rdi
leaq 0x3abf(%rip), %rsi      # 0x6349
callq 0x2310
movq %rax, -0x48(%rbp)
cmpq $0x0, (%r15)
sete %al
pushq $0x1
popq %r12
leaq -0x60(%rbp), %r13
movl $0x0, -0x38(%rbp)
movl %r12d, %ecx
movq %rcx, -0x58(%rbp)
movl $0x0, -0x5c(%rbp)
movl $0x0, -0x3c(%rbp)
movl $0x0, -0x2c(%rbp)
movl $0x0, -0x50(%rbp)
movl $0x0, -0x30(%rbp)
movl %r12d, -0x4c(%rbp)
testb $0x1, %al
je 0x28f8
movq -0x68(%rbp), %rdi
movq %r15, %rsi
movq %r13, %rdx
callq 0x3634
testl %eax, %eax
js 0x2bf9
cmpq $0x0, (%r15)
je 0x28db
movl -0x38(%rbp), %eax
cmpl (%r14), %eax
jb 0x29a4
cmpl $0x0, -0x2c(%rbp)
je 0x2a80
movq -0x48(%rbp), %rdi
callq 0x2110
movl -0x3c(%rbp), %r12d
addl -0x38(%rbp), %r12d
movq -0x58(%rbp), %rax
cmpl 0x4(%r14), %eax
jae 0x2c60
movq 0x30(%r14), %rdi
movq -0x78(%rbp), %r13
movq %r13, %rsi
leaq 0x3a93(%rip), %rdx      # 0x63d2
callq 0x4d5b
movq 0x10(%rbx), %rcx
movq %rcx, -0x38(%rbp)
movl %r12d, -0x3c(%rbp)
movl -0x58(%rbp), %r12d
movq %rax, (%rcx,%r12,8)
movq 0x30(%r14), %rdi
movq %r13, %rsi
leaq -0x60(%rbp), %r13
leaq 0x3a6c(%rip), %rdx      # 0x63d6
callq 0x4d5b
movq 0x18(%rbx), %rcx
movq %rax, (%rcx,%r12,8)
movq -0x38(%rbp), %rax
movq (%rax,%r12,8), %rdi
pushq $0x1
popq %r12
leaq 0x39bf(%rip), %rsi      # 0x6349
callq 0x2310
movq %rax, -0x48(%rbp)
movq -0x58(%rbp), %rax
incl %eax
movq %rax, -0x58(%rbp)
movl $0x0, -0x38(%rbp)
cmpl $0x0, -0x2c(%rbp)
jne 0x29f3
movq 0x10(%r15), %rdi
movb (%rdi), %al
cmpb $0x40, %al
je 0x2aac
movzbl %al, %eax
cmpl $0x3e, %eax
jne 0x29f3
callq 0x37e8
movl $0x0, -0x2c(%rbp)
testl %eax, %eax
jne 0x2d4d
movq 0x10(%r15), %rdx
movq -0x48(%rbp), %rdi
leaq 0x3b3c(%rip), %rsi      # 0x651f
xorl %eax, %eax
callq 0x2220
movl %r12d, -0x30(%rbp)
jmp 0x2bcc
movq 0x10(%r15), %rdx
cmpl $0x0, -0x30(%rbp)
je 0x2a21
movq -0x48(%rbp), %rdi
leaq 0x3b17(%rip), %rsi      # 0x651f
xorl %eax, %eax
callq 0x2220
movl -0x38(%rbp), %eax
addl (%r15), %eax
movl %eax, -0x38(%rbp)
movl %r12d, -0x30(%rbp)
jmp 0x2bcf
cmpb $0x53, (%rdx)
jne 0x2b62
leaq 0x2(%rdx), %r13
addq $0x3, %rdx
xorl %eax, %eax
xorl %ecx, %ecx
movzbl -0x1(%rdx), %edi
cmpl $0x9, %edi
je 0x2a43
testl %edi, %edi
jne 0x2a69
movb $0x0, -0x1(%rdx)
testl %ecx, %ecx
movq %rax, %rsi
cmoveq %r13, %rsi
cmpl $0x1, %ecx
je 0x2b6f
movl %r12d, %r8d
movq %rdx, %r9
testb %dil, %dil
jne 0x2a72
jmp 0x2b6f
movq %rax, %rsi
movl %ecx, %r8d
movq %r13, %r9
incq %rdx
movq %rsi, %rax
movl %r8d, %ecx
movq %r9, %r13
jmp 0x2a36
movq 0x10(%r15), %rdi
cmpl $0x0, -0x30(%rbp)
je 0x2a93
cmpb $0x3e, (%rdi)
je 0x290e
cmpl $0x0, -0x50(%rbp)
je 0x29ae
movb (%rdi), %al
cmpb $0x40, %al
je 0x290e
jmp 0x29b0
callq 0x37e8
movl %eax, %r12d
testl %eax, %eax
jne 0x2ad1
movq 0x10(%r15), %rdx
incq %rdx
movq -0x48(%rbp), %rdi
leaq 0x3911(%rip), %rsi      # 0x63db
xorl %eax, %eax
callq 0x2220
movq -0x68(%rbp), %rdi
movq %r15, %rsi
movq %r13, %rdx
callq 0x3634
testl %eax, %eax
pushq $0x2
popq %rax
cmovsl %eax, %r12d
testl %r12d, %r12d
movl %r12d, -0x2c(%rbp)
jne 0x2b11
movq 0x10(%r15), %rdx
movq -0x48(%rbp), %rdi
leaq 0x3a1e(%rip), %rsi      # 0x651f
xorl %eax, %eax
callq 0x2220
movl -0x38(%rbp), %eax
addl (%r15), %eax
movl %eax, -0x38(%rbp)
movq -0x68(%rbp), %r12
movq %r12, %rdi
movq %r15, %rsi
movq %r13, %rdx
callq 0x3634
testl %eax, %eax
js 0x2d1d
movq %r12, %rdi
movq %r15, %rsi
movq %r13, %rdx
callq 0x3634
testl %eax, %eax
js 0x2d1d
movl -0x2c(%rbp), %r8d
testl %r8d, %r8d
pushq $0x1
popq %r12
jne 0x2d21
incl -0x5c(%rbp)
movl $0x0, -0x2c(%rbp)
movl %r12d, -0x50(%rbp)
jmp 0x2bcf
movl $0x0, -0x30(%rbp)
movl %r12d, -0x2c(%rbp)
jmp 0x2bcf
movb $0x1, %dl
movl %edx, -0x2c(%rbp)
cmpl $0x1, %ecx
jne 0x2d43
cmpb $0x2a, (%r13)
je 0x2d47
movl $0x0, -0x30(%rbp)
movq -0x48(%rbp), %rdi
leaq 0x3841(%rip), %rsi      # 0x63db
movq %rax, %rdx
xorl %eax, %eax
callq 0x2220
movq -0x48(%rbp), %rdi
leaq 0x3970(%rip), %rsi      # 0x651f
movq %r13, %rdx
xorl %eax, %eax
callq 0x2220
movq %r13, %rdi
callq 0x2130
addl %eax, -0x38(%rbp)
movl %r12d, -0x2c(%rbp)
leaq -0x60(%rbp), %r13
incl -0x5c(%rbp)
andq $0x0, (%r15)
movb $0x1, %al
jmp 0x28d7
movq 0x10(%rbx), %rdi
callq 0x2050
movq 0x18(%rbx), %rdi
callq 0x2050
movq %rbx, %rdi
callq 0x2050
jmp 0x2c96
movq -0x48(%rbp), %rdi
testq %rdi, %rdi
je 0x2c5c
callq 0x2110
movl -0x38(%rbp), %eax
movl -0x3c(%rbp), %r12d
addl %eax, %r12d
testl %eax, %eax
jne 0x2c60
movl %r12d, %r13d
movq -0x58(%rbp), %r12
decl %r12d
movq 0x10(%rbx), %r15
movq (%r15,%r12,8), %rdi
callq 0x2080
movl %r13d, -0x3c(%rbp)
movq %r12, %r13
movq %r12, -0x58(%rbp)
movq 0x18(%rbx), %r12
movq (%r12,%r13,8), %rdi
callq 0x2080
movq (%r15,%r13,8), %rdi
callq 0x2050
movq (%r12,%r13,8), %rdi
movl -0x3c(%rbp), %r12d
callq 0x2050
jmp 0x2c60
movl -0x3c(%rbp), %r12d
movl -0x50(%rbp), %eax
addl -0x2c(%rbp), %eax
addl -0x30(%rbp), %eax
cmpl $0x2, %eax
jge 0x2cfe
cmpl $0x0, -0x58(%rbp)
jne 0x2caa
movq 0x10(%rbx), %rdi
callq 0x2050
movq 0x18(%rbx), %rdi
callq 0x2050
movq %rbx, %rdi
callq 0x2050
movq -0x70(%rbp), %rsp
xorl %ebx, %ebx
movq %rbx, %rax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq -0x58(%rbp), %r9
movl %r9d, 0x8(%rbx)
movq %r14, (%rbx)
movq 0x6334(%rip), %rax      # 0x8ff0
movq (%rax), %rdi
cmpl $0x1, %r9d
leaq 0x339e(%rip), %rax      # 0x6068
leaq 0x37f5(%rip), %r10      # 0x64c6
cmoveq %rax, %r10
subq $0x8, %rsp
leaq 0x37b4(%rip), %rsi      # 0x6494
leaq 0x372b(%rip), %rdx      # 0x6412
movl -0x5c(%rbp), %ecx
movl %r12d, %r8d
xorl %eax, %eax
pushq %r10
callq 0x2220
popq %rcx
popq %rdx
movq -0x70(%rbp), %rsp
jmp 0x2c98
leaq 0x3733(%rip), %rdi      # 0x6438
leaq 0x3748(%rip), %rsi      # 0x6454
leaq 0x3750(%rip), %rcx      # 0x6463
movl $0xf5, %edx
callq 0x2180
pushq $0x3
popq %r8
movq 0x62c8(%rip), %rax      # 0x8ff0
movq (%rax), %rdi
cmpl $0x0, -0x30(%rbp)
jne 0x2d3a
leaq 0x36f6(%rip), %rcx      # 0x642e
jmp 0x2d7e
leaq 0x36e7(%rip), %rcx      # 0x6428
jmp 0x2d7e
pushq $0x5
jmp 0x2d49
pushq $0x6
popq %rax
movl %eax, -0x4c(%rbp)
movq 0x629c(%rip), %rax      # 0x8ff0
movq (%rax), %rdi
cmpl $0x0, -0x50(%rbp)
leaq 0x36d2(%rip), %rax      # 0x6434
leaq 0x36c5(%rip), %rcx      # 0x642e
cmoveq %rax, %rcx
cmpb $0x0, -0x2c(%rbp)
jne 0x2d7a
leaq 0x36ae(%rip), %rcx      # 0x6428
movl -0x4c(%rbp), %r8d
leaq 0x365b(%rip), %rsi      # 0x63e0
leaq 0x3686(%rip), %rdx      # 0x6412
xorl %eax, %eax
callq 0x2220
pushq $0x1
popq %rdi
callq 0x2370