// File: /workspace/github_c_makefile_star2_O0/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
subq $0xe0, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x28(%rbp)
cmpl $0x0, -0x14(%rbp)
jne 0x2f13
movl $0x1, %edi
movl $0x20, %esi
callq 0x21f0
movq %rax, -0x30(%rbp)
movq -0x28(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, %edi
shlq $0x3, %rdi
callq 0x2280
movq %rax, %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x28(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, %edi
shlq $0x3, %rdi
callq 0x2280
movq %rax, %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x28(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x28(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x28(%rbp), %rax
movq 0x30(%rax), %rdi
callq 0x2130
movq %rax, %rcx
movq %rcx, %rax
addq $0x10, %rax
movq %rsp, %rdx
movq %rdx, -0x78(%rbp)
addq $0x1f, %rcx
andq $-0x10, %rcx
movq %rsp, %rsi
subq %rcx, %rsi
movq %rsi, -0xc0(%rbp)
movq %rsi, %rsp
movq %rax, -0x80(%rbp)
movl $0x0, -0x54(%rbp)
movl $0x0, -0x50(%rbp)
movl $0x0, -0x4c(%rbp)
movl $0x0, -0x5c(%rbp)
movl $0x0, -0x58(%rbp)
movq $0x0, -0x70(%rbp)
movl $0x0, -0x64(%rbp)
movl $0x0, -0x60(%rbp)
movq -0x28(%rbp), %rax
movq 0x30(%rax), %rdi
leaq 0x6ad0(%rip), %rdx      # 0x93ef
callq 0x6d80
movq -0xc0(%rbp), %rsi
movq %rax, %rdx
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x5c(%rbp), %ecx
movq %rdx, (%rax,%rcx,8)
movq -0x28(%rbp), %rax
movq 0x30(%rax), %rdi
leaq 0x6aa7(%rip), %rdx      # 0x93f3
callq 0x6d80
movq %rax, %rdx
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rax
movl -0x5c(%rbp), %ecx
movq %rdx, (%rax,%rcx,8)
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x5c(%rbp), %ecx
movq (%rax,%rcx,8), %rdi
leaq 0x69d2(%rip), %rsi      # 0x934b
callq 0x2310
movq %rax, -0x70(%rbp)
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
movq -0x40(%rbp), %rcx
movb $0x1, %al
cmpq $0x0, (%rcx)
movb %al, -0xc1(%rbp)
jne 0x29bf
movq -0x38(%rbp), %rdi
movq -0x40(%rbp), %rdx
movl $0x2, %esi
leaq -0x44(%rbp), %rcx
callq 0x3cc0
cmpl $0x0, %eax
setge %al
movb %al, -0xc1(%rbp)
movb -0xc1(%rbp), %al
testb $0x1, %al
jne 0x29ce
jmp 0x2da1
movq -0x40(%rbp), %rax
cmpq $0x0, (%rax)
jne 0x29da
jmp 0x298b
movl -0x58(%rbp), %eax
movq -0x28(%rbp), %rcx
cmpl (%rcx), %eax
jb 0x2ad9
cmpl $0x0, -0x54(%rbp)
jne 0x2a23
cmpl $0x0, -0x4c(%rbp)
je 0x2a05
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rax
movsbl (%rax), %eax
cmpl $0x3e, %eax
je 0x2a23
cmpl $0x0, -0x50(%rbp)
je 0x2ad9
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rax
movsbl (%rax), %eax
cmpl $0x40, %eax
jne 0x2ad9
movq -0x70(%rbp), %rdi
callq 0x2110
movq $0x0, -0x70(%rbp)
movl -0x58(%rbp), %eax
addl -0x64(%rbp), %eax
movl %eax, -0x64(%rbp)
movl -0x5c(%rbp), %eax
movq -0x28(%rbp), %rcx
cmpl 0x4(%rcx), %eax
jb 0x2a4e
jmp 0x2da1
movq -0xc0(%rbp), %rsi
movq -0x28(%rbp), %rax
movq 0x30(%rax), %rdi
leaq 0x698b(%rip), %rdx      # 0x93ef
callq 0x6d80
movq -0xc0(%rbp), %rsi
movq %rax, %rdx
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x5c(%rbp), %ecx
movq %rdx, (%rax,%rcx,8)
movq -0x28(%rbp), %rax
movq 0x30(%rax), %rdi
leaq 0x6962(%rip), %rdx      # 0x93f3
callq 0x6d80
movq %rax, %rdx
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rax
movl -0x5c(%rbp), %ecx
movq %rdx, (%rax,%rcx,8)
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x5c(%rbp), %ecx
movq (%rax,%rcx,8), %rdi
leaq 0x688d(%rip), %rsi      # 0x934b
callq 0x2310
movq %rax, -0x70(%rbp)
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
movl $0x0, -0x58(%rbp)
jmp 0x2ad9
movl $0x0, -0x48(%rbp)
cmpl $0x0, -0x54(%rbp)
jne 0x2b3b
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rax
movsbl (%rax), %eax
cmpl $0x3e, %eax
jne 0x2b3b
movl $0x1, -0x4c(%rbp)
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x3d00
movl %eax, -0x48(%rbp)
cmpl $0x0, -0x48(%rbp)
jne 0x2b2d
movq -0x70(%rbp), %rdi
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rdx
leaq 0x6a16(%rip), %rsi      # 0x953c
movb $0x0, %al
callq 0x2220
movl -0x60(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x60(%rbp)
jmp 0x2d14
cmpl $0x0, -0x54(%rbp)
jne 0x2c31
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rax
movsbl (%rax), %eax
cmpl $0x40, %eax
jne 0x2c31
movl $0x1, -0x50(%rbp)
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x3d00
movl %eax, -0x48(%rbp)
cmpl $0x0, -0x48(%rbp)
jne 0x2b94
movq -0x70(%rbp), %rdi
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rdx
addq $0x1, %rdx
leaq 0x686b(%rip), %rsi      # 0x93f8
movb $0x0, %al
callq 0x2220
movq -0x38(%rbp), %rdi
movq -0x40(%rbp), %rdx
movl $0x2, %esi
leaq -0x44(%rbp), %rcx
callq 0x3cc0
cmpl $0x0, %eax
jge 0x2bb6
movl $0x2, -0x48(%rbp)
cmpl $0x0, -0x48(%rbp)
jne 0x2be6
movq -0x70(%rbp), %rdi
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rdx
leaq 0x696d(%rip), %rsi      # 0x953c
movb $0x0, %al
callq 0x2220
movq -0x40(%rbp), %rax
movq (%rax), %rcx
movl -0x58(%rbp), %eax
addq %rcx, %rax
movl %eax, -0x58(%rbp)
movq -0x38(%rbp), %rdi
movq -0x40(%rbp), %rdx
movl $0x2, %esi
leaq -0x44(%rbp), %rcx
callq 0x3cc0
cmpl $0x0, %eax
jl 0x2c1c
movq -0x38(%rbp), %rdi
movq -0x40(%rbp), %rdx
movl $0x2, %esi
leaq -0x44(%rbp), %rcx
callq 0x3cc0
cmpl $0x0, %eax
jge 0x2c23
movl $0x3, -0x48(%rbp)
movl -0x60(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x60(%rbp)
jmp 0x2d12
cmpl $0x0, -0x4c(%rbp)
je 0x2c66
movq -0x70(%rbp), %rdi
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rdx
leaq 0x68f2(%rip), %rsi      # 0x953c
movb $0x0, %al
callq 0x2220
movq -0x40(%rbp), %rax
movq (%rax), %rcx
movl -0x58(%rbp), %eax
addq %rcx, %rax
movl %eax, -0x58(%rbp)
jmp 0x2d10
movl $0x1, -0x54(%rbp)
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rax
movsbl (%rax), %eax
cmpl $0x53, %eax
jne 0x2d0e
movq $0x0, -0x90(%rbp)
movq $0x0, -0x88(%rbp)
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rdi
leaq -0x88(%rbp), %rsi
leaq -0x90(%rbp), %rdx
callq 0x3da0
movl %eax, -0x48(%rbp)
cmpl $0x0, -0x48(%rbp)
jne 0x2d05
movq -0x70(%rbp), %rdi
movq -0x88(%rbp), %rdx
leaq 0x672b(%rip), %rsi      # 0x93f8
movb $0x0, %al
callq 0x2220
movq -0x70(%rbp), %rdi
movq -0x90(%rbp), %rdx
leaq 0x6856(%rip), %rsi      # 0x953c
movb $0x0, %al
callq 0x2220
movq -0x90(%rbp), %rdi
callq 0x2130
movq %rax, %rcx
movl -0x58(%rbp), %eax
addq %rcx, %rax
movl %eax, -0x58(%rbp)
movl -0x60(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x60(%rbp)
jmp 0x2d10
jmp 0x2d12
jmp 0x2d14
cmpl $0x0, -0x48(%rbp)
je 0x2d91
movq 0x92d7(%rip), %rax      # 0xbff8
movq (%rax), %rax
movq %rax, -0xd0(%rbp)
cmpl $0x0, -0x4c(%rbp)
je 0x2d41
leaq 0x670d(%rip), %rax      # 0x9445
movq %rax, -0xd8(%rbp)
jmp 0x2d60
movl -0x50(%rbp), %edx
leaq 0x6706(%rip), %rax      # 0x9451
leaq 0x66f9(%rip), %rcx      # 0x944b
cmpl $0x0, %edx
cmovneq %rcx, %rax
movq %rax, -0xd8(%rbp)
movq -0xd0(%rbp), %rdi
movq -0xd8(%rbp), %rcx
movl -0x48(%rbp), %r8d
leaq 0x6684(%rip), %rsi      # 0x93fd
leaq 0x66af(%rip), %rdx      # 0x942f
movb $0x0, %al
callq 0x2220
movl $0x1, %edi
callq 0x2370
movq -0x40(%rbp), %rax
movq $0x0, (%rax)
jmp 0x298b
cmpq $0x0, -0x70(%rbp)
je 0x2e1b
movq -0x70(%rbp), %rdi
callq 0x2110
movl -0x58(%rbp), %eax
addl -0x64(%rbp), %eax
movl %eax, -0x64(%rbp)
cmpl $0x0, -0x58(%rbp)
jne 0x2e19
movl -0x5c(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x5c(%rbp)
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x5c(%rbp), %ecx
movq (%rax,%rcx,8), %rdi
callq 0x2080
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rax
movl -0x5c(%rbp), %ecx
movq (%rax,%rcx,8), %rdi
callq 0x2080
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x5c(%rbp), %ecx
movq (%rax,%rcx,8), %rdi
callq 0x2050
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rax
movl -0x5c(%rbp), %ecx
movq (%rax,%rcx,8), %rdi
callq 0x2050
jmp 0x2e1b
movl -0x4c(%rbp), %eax
addl -0x50(%rbp), %eax
addl -0x54(%rbp), %eax
cmpl $0x1, %eax
jg 0x2e2b
jmp 0x2e4a
leaq 0x6623(%rip), %rdi      # 0x9455
leaq 0x6638(%rip), %rsi      # 0x9471
movl $0xf5, %edx
leaq 0x663b(%rip), %rcx      # 0x9480
callq 0x2190
cmpl $0x0, -0x5c(%rbp)
jne 0x2e75
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x2050
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x2050
movq -0x30(%rbp), %rdi
callq 0x2050
jmp 0x2eec
movl -0x5c(%rbp), %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x8(%rax)
movq -0x28(%rbp), %rcx
movq -0x30(%rbp), %rax
movq %rcx, (%rax)
movq 0x9167(%rip), %rax      # 0xbff8
movq (%rax), %rdi
movl -0x60(%rbp), %ecx
movl -0x64(%rbp), %r8d
movl -0x5c(%rbp), %r9d
movl -0x5c(%rbp), %esi
leaq 0x61c1(%rip), %rax      # 0x906a
leaq 0x6633(%rip), %rdx      # 0x94e3
cmpl $0x1, %esi
cmovaq %rdx, %rax
leaq 0x65f3(%rip), %rsi      # 0x94b1
leaq 0x656a(%rip), %rdx      # 0x942f
subq $0x10, %rsp
movq %rax, (%rsp)
movb $0x0, %al
callq 0x2220
addq $0x10, %rsp
movq -0x30(%rbp), %rax
movq %rax, -0x8(%rbp)
movl $0x1, -0x94(%rbp)
jmp 0x2ef6
movl $0x0, -0x94(%rbp)
movq -0x78(%rbp), %rax
movq %rax, %rsp
movl -0x94(%rbp), %eax
testl %eax, %eax
je 0x2f0e
jmp 0x2f09
jmp 0x3097
jmp 0x308f
cmpl $0x1, -0x14(%rbp)
jne 0x2f45
movq -0x28(%rbp), %rax
movl 0x38(%rax), %edi
movq -0x20(%rbp), %rdx
movq -0x20(%rbp), %rax
movslq 0x8(%rax), %rcx
leaq 0xf6d(%rip), %rsi       # 0x3ea0
callq 0x7cd0
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x3097
cmpl $0x2, -0x14(%rbp)
jne 0x308b
movq -0x20(%rbp), %rax
movq %rax, -0xa0(%rbp)
movl $0x0, -0xa4(%rbp)
movl -0xa4(%rbp), %eax
movq -0xa0(%rbp), %rcx
cmpl 0x8(%rcx), %eax
jge 0x305f
movq -0xa0(%rbp), %rax
movq 0x18(%rax), %rax
movslq -0xa4(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x65b8(%rip), %rsi      # 0x954f
callq 0x2310
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rdi
callq 0x21b0
movb %al, -0xb1(%rbp)
movsbl %al, %eax
cmpl $-0x1, %eax
je 0x2fd3
movsbl -0xb1(%rbp), %edi
movq -0x28(%rbp), %rax
movq 0x28(%rax), %rsi
callq 0x21d0
jmp 0x2fa3
movq -0xb0(%rbp), %rdi
callq 0x2110
movq -0xa0(%rbp), %rax
movq 0x10(%rax), %rax
movslq -0xa4(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x2080
movq -0xa0(%rbp), %rax
movq 0x18(%rax), %rax
movslq -0xa4(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x2080
movq -0xa0(%rbp), %rax
movq 0x10(%rax), %rax
movslq -0xa4(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x2050
movq -0xa0(%rbp), %rax
movq 0x18(%rax), %rax
movslq -0xa4(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x2050
movl -0xa4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa4(%rbp)
jmp 0x2f64
movq -0xa0(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x2050
movq -0xa0(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x2050
movq -0xa0(%rbp), %rdi
callq 0x2050
jmp 0x308d
jmp 0x308f
movq $0x0, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rbp, %rsp
popq %rbp
retq