// File: /workspace/github_c_makefile_star2_O1/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 0x2c37
movq %rdx, %rbx
cmpl $0x1, %esi
je 0x2c1b
cmpl $0x2, %esi
jne 0x3124
cmpl $0x0, 0x8(%rbx)
jle 0x2bfc
xorl %r13d, %r13d
leaq 0x49b8(%rip), %r15      # 0x7534
movq 0x18(%rbx), %rax
movq (%rax,%r13,8), %rdi
movq %r15, %rsi
callq 0x2310
movq %rax, %r12
movq %rax, %rdi
callq 0x21a0
shll $0x18, %eax
cmpl $0xff000000, %eax       # imm = 0xFF000000
je 0x2bb4
sarl $0x18, %eax
movq 0x28(%r14), %rsi
movl %eax, %edi
callq 0x21c0
movq %r12, %rdi
jmp 0x2b92
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
movslq 0x8(%rbx), %rax
cmpq %rax, %r13
jl 0x2b7c
movq 0x10(%rbx), %rdi
callq 0x2050
movq 0x18(%rbx), %rdi
callq 0x2050
movq %rbx, %rdi
callq 0x2050
jmp 0x3124
movl 0x38(%r14), %edi
movslq 0x8(%rbx), %rcx
leaq 0xf77(%rip), %rsi       # 0x3ba1
movq %rbx, %rdx
callq 0x5bbc
jmp 0x3126
movl $0x1, %edi
movl $0x20, %esi
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, -0x60(%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 0x472f(%rip), %rdx      # 0x73d4
movq %r12, %rsi
callq 0x53ec
movq %rax, (%r13)
movq 0x30(%r14), %rdi
leaq 0x471c(%rip), %rdx      # 0x73d8
movq %r12, -0x78(%rbp)
movq %r12, %rsi
callq 0x53ec
movq -0x38(%rbp), %rcx
movq %rax, (%rcx)
movq (%r13), %rdi
movq -0x60(%rbp), %r13
leaq 0x466d(%rip), %rsi      # 0x734b
callq 0x2310
movq %rax, -0x58(%rbp)
movl $0x1, %eax
movq %rax, -0x40(%rbp)
movl $0x0, -0x38(%rbp)
movl $0x0, -0x48(%rbp)
movl $0x0, -0x64(%rbp)
movl $0x0, -0x30(%rbp)
movl $0x0, -0x4c(%rbp)
movl $0x0, -0x2c(%rbp)
cmpq $0x0, (%r15)
jne 0x2d37
movq %r13, %rdi
movq %r15, %rsi
leaq -0x68(%rbp), %rdx
callq 0x39da
testl %eax, %eax
js 0x3096
cmpq $0x0, (%r15)
je 0x2d1a
movl -0x38(%rbp), %r13d
cmpl (%r14), %r13d
jb 0x2dda
cmpl $0x0, -0x30(%rbp)
je 0x2ee2
movq -0x58(%rbp), %rdi
callq 0x2110
addl %r13d, -0x64(%rbp)
movq -0x40(%rbp), %rax
cmpl 0x4(%r14), %eax
jae 0x318b
movq 0x30(%r14), %rdi
movq -0x78(%rbp), %r13
movq %r13, %rsi
leaq 0x4653(%rip), %rdx      # 0x73d4
callq 0x53ec
movq 0x10(%rbx), %rcx
movq %rcx, -0x38(%rbp)
movl -0x40(%rbp), %r12d
movq %rax, (%rcx,%r12,8)
movq 0x30(%r14), %rdi
movq %r13, %rsi
leaq 0x4634(%rip), %rdx      # 0x73d8
callq 0x53ec
movq 0x18(%rbx), %rcx
movq %rax, (%rcx,%r12,8)
movq -0x38(%rbp), %rax
movq (%rax,%r12,8), %rdi
leaq 0x458b(%rip), %rsi      # 0x734b
callq 0x2310
movq %rax, -0x58(%rbp)
movq -0x40(%rbp), %rax
incl %eax
movq %rax, -0x40(%rbp)
movl $0x0, -0x38(%rbp)
cmpl $0x0, -0x30(%rbp)
je 0x2e18
cmpl $0x0, -0x2c(%rbp)
je 0x2e98
movq 0x10(%r15), %rdx
movq -0x58(%rbp), %rdi
leaq 0x4728(%rip), %rsi      # 0x7521
xorl %eax, %eax
callq 0x2220
xorl %r8d, %r8d
movl -0x38(%rbp), %eax
addl (%r15), %eax
movl %eax, -0x38(%rbp)
movl $0x1, -0x2c(%rbp)
jmp 0x2f22
movq 0x10(%r15), %r12
movzbl (%r12), %r13d
cmpl $0x40, %r13d
je 0x2fb5
cmpl $0x3e, %r13d
jne 0x2de0
callq 0x23f0
movq (%rax), %rcx
movq %r12, %rax
movsbq %r13b, %rdx
testb $0x20, 0x1(%rcx,%rdx,2)
jne 0x2e53
movb 0x1(%rax), %r13b
incq %rax
testb %r13b, %r13b
jne 0x2e3c
movb $0x0, (%rax)
subq %r12, %rax
xorl %r8d, %r8d
cmpq $0x1, %rax
sete %r13b
je 0x2e7f
movq 0x10(%r15), %rdx
movq -0x58(%rbp), %rdi
leaq 0x46ac(%rip), %rsi      # 0x7521
xorl %eax, %eax
callq 0x2220
xorl %r8d, %r8d
movb %r13b, %r8b
incl -0x48(%rbp)
movl $0x1, -0x2c(%rbp)
movl $0x0, -0x30(%rbp)
jmp 0x2f22
movq 0x10(%r15), %rax
cmpb $0x53, (%rax)
jne 0x2f11
leaq 0x2(%rax), %rsi
addq $0x3, %rax
xorl %edx, %edx
xorl %r13d, %r13d
xorl %ecx, %ecx
movzbl -0x1(%rax), %edi
cmpl $0x9, %edi
je 0x2ebd
testl %edi, %edi
jne 0x2edd
testl %ecx, %ecx
cmoveq %rsi, %rdx
movb $0x0, -0x1(%rax)
cmovneq %rsi, %r13
cmpl $0x1, %ecx
je 0x2f3b
testb %dil, %dil
je 0x2f3b
movl $0x1, %ecx
movq %rax, %rsi
incq %rax
jmp 0x2eb0
cmpl $0x0, -0x2c(%rbp)
je 0x2ef5
movq 0x10(%r15), %rax
cmpb $0x3e, (%rax)
je 0x2d54
cmpl $0x0, -0x4c(%rbp)
je 0x2dda
movq 0x10(%r15), %rax
cmpb $0x40, (%rax)
je 0x2d54
jmp 0x2dda
movl $0x0, -0x2c(%rbp)
movl $0x1, -0x30(%rbp)
xorl %r8d, %r8d
movq -0x60(%rbp), %r13
testl %r8d, %r8d
jne 0x3192
movq $0x0, (%r15)
jmp 0x2d1a
movl $0x5, %r8d
cmpl $0x1, %ecx
jne 0x2f5a
cmpb $0x2a, (%r13)
movl $0x0, %r8d
movl $0x6, %eax
cmovel %eax, %r8d
testl %r8d, %r8d
jne 0x2f9b
movq -0x58(%rbp), %r12
movq %r12, %rdi
leaq 0x4470(%rip), %rsi      # 0x73dd
xorl %eax, %eax
movl %r8d, -0x44(%rbp)
callq 0x2220
movq %r12, %rdi
leaq 0x459f(%rip), %rsi      # 0x7521
movq %r13, %rdx
xorl %eax, %eax
callq 0x2220
movq %r13, %rdi
callq 0x2130
movl -0x44(%rbp), %r8d
addl %eax, -0x38(%rbp)
movq -0x60(%rbp), %r13
incl -0x48(%rbp)
movl $0x0, -0x2c(%rbp)
movl $0x1, -0x30(%rbp)
jmp 0x2f26
callq 0x23f0
movq (%rax), %rcx
movq %r12, %rax
movsbq %r13b, %rdx
testb $0x20, 0x1(%rcx,%rdx,2)
jne 0x2fd7
movb 0x1(%rax), %r13b
incq %rax
testb %r13b, %r13b
jne 0x2fc0
movb $0x0, (%rax)
subq %r12, %rax
xorl %r12d, %r12d
cmpq $0x1, %rax
sete %r13b
je 0x3006
movq 0x10(%r15), %rdx
incq %rdx
movq -0x58(%rbp), %rdi
leaq 0x43e1(%rip), %rsi      # 0x73dd
xorl %eax, %eax
callq 0x2220
xorl %r12d, %r12d
movb %r13b, %r12b
movq -0x60(%rbp), %r13
movq %r13, %rdi
movq %r15, %rsi
leaq -0x68(%rbp), %rdx
callq 0x39da
testl %eax, %eax
movl $0x2, %eax
cmovsl %eax, %r12d
movl %r12d, -0x44(%rbp)
testl %r12d, %r12d
jne 0x304f
movq 0x10(%r15), %rdx
movq -0x58(%rbp), %rdi
leaq 0x44e2(%rip), %rsi      # 0x7521
xorl %eax, %eax
callq 0x2220
movl -0x38(%rbp), %eax
addl (%r15), %eax
movl %eax, -0x38(%rbp)
movq %r13, %rdi
movq %r15, %rsi
leaq -0x68(%rbp), %rdx
callq 0x39da
testl %eax, %eax
js 0x3075
movq %r13, %rdi
movq %r15, %rsi
leaq -0x68(%rbp), %rdx
callq 0x39da
testl %eax, %eax
jns 0x307c
movl $0x3, -0x44(%rbp)
incl -0x48(%rbp)
movl $0x1, -0x4c(%rbp)
movl $0x0, -0x30(%rbp)
movl -0x44(%rbp), %r8d
jmp 0x2f26
movl -0x38(%rbp), %r13d
movq -0x58(%rbp), %rdi
testq %rdi, %rdi
je 0x30e8
callq 0x2110
addl %r13d, -0x64(%rbp)
testl %r13d, %r13d
jne 0x30e8
movq -0x40(%rbp), %r13
decl %r13d
movq 0x10(%rbx), %r15
movq (%r15,%r13,8), %rdi
callq 0x2080
movq %r13, -0x40(%rbp)
movq 0x18(%rbx), %r12
movq (%r12,%r13,8), %rdi
callq 0x2080
movq (%r15,%r13,8), %rdi
callq 0x2050
movq (%r12,%r13,8), %rdi
callq 0x2050
movl -0x4c(%rbp), %eax
addl -0x30(%rbp), %eax
addl -0x2c(%rbp), %eax
cmpl $0x2, %eax
jge 0x31a0
cmpl $0x0, -0x40(%rbp)
jne 0x3138
movq 0x10(%rbx), %rdi
callq 0x2050
movq 0x18(%rbx), %rdi
callq 0x2050
movq %rbx, %rdi
callq 0x2050
cmpl $0x0, -0x40(%rbp)
movq -0x70(%rbp), %rsp
jne 0x3126
xorl %ebx, %ebx
movq %rbx, %rax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq -0x40(%rbp), %r9
movl %r9d, 0x8(%rbx)
movq %r14, (%rbx)
movq 0x6ea6(%rip), %rax      # 0x9ff0
movq (%rax), %rdi
cmpl $0x1, %r9d
leaq 0x3f12(%rip), %rax      # 0x706a
leaq 0x4369(%rip), %r10      # 0x74c8
cmoveq %rax, %r10
subq $0x8, %rsp
leaq 0x4328(%rip), %rsi      # 0x7496
leaq 0x429f(%rip), %rdx      # 0x7414
movl -0x48(%rbp), %ecx
movl -0x64(%rbp), %r8d
xorl %eax, %eax
pushq %r10
callq 0x2220
addq $0x10, %rsp
jmp 0x311a
xorl %edi, %edi
jmp 0x309e
movl -0x2c(%rbp), %edi
movl -0x4c(%rbp), %esi
movl %r8d, %edx
callq 0x243f
leaq 0x4293(%rip), %rdi      # 0x743a
leaq 0x42a8(%rip), %rsi      # 0x7456
leaq 0x42b0(%rip), %rcx      # 0x7465
movl $0xf5, %edx
callq 0x2180