// File: MITRECND[P]snugglefish/src/snugglefish.cpp
// Function: make_index
void make_index(string indexFileName, vector <string> fileNames, uint32_t ngramSize, uint32_t max_files, uint64_t max_buffer, uint32_t threads){

    pthread_t* indexers;
    mi_data* midata;
    void* status;


    midata = new mi_data;
    indexers = (pthread_t*) malloc(threads * sizeof(pthread_t));


    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

    pthread_mutex_init(& (midata->filesMutex), NULL);
    pthread_mutex_init(& (midata->nGramIndexMutex), NULL);

    midata->fileList = & fileNames;
    midata->ngramSize = ngramSize;
    midata->queue = 0;

    try{
        nGramIndex ngramindex(ngramSize, indexFileName);
        if (max_buffer > 0){
            ngramindex.setmaxBufferSize(max_buffer);
        }

        midata->ngramindex = &ngramindex;

        for(uint32_t i = 0; i < threads; i++){
            pthread_create(& indexers[i], & attr, indexerThread, (void*) midata);
        }

        while(1){
            //Usage of mutex shouldn't matter
            if (midata->queue >= fileNames.size()){
                break;
            }
            
            printStats(&ngramindex, midata->queue, fileNames.size());
            sleep(1);
        }


        for(uint32_t i = 0; i < threads; i++){
            pthread_join(indexers[i], &status);
        }

        //Print some final stats
        printStats(&ngramindex, midata->queue, fileNames.size());
        cerr << endl;

    } catch (exception& e){
        cout << "Error:" << e.what() << endl;
        handler(SIGSEGV);
    }


    pthread_mutex_destroy(&(midata->filesMutex));
    pthread_mutex_destroy(&(midata->nGramIndexMutex));
    pthread_attr_destroy(&attr);

    delete midata;
    free(indexers);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1a0, %rsp            # imm = 0x1A0
movq %rdi, -0x150(%rbp)
movq %rsi, -0x158(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl %ecx, -0x18(%rbp)
movq %r8, -0x20(%rbp)
movl %r9d, -0x24(%rbp)
movl $0x70, %edi
callq 0xe300
movq %rax, -0x38(%rbp)
movl -0x24(%rbp), %eax
movl %eax, %edi
shlq $0x3, %rdi
callq 0xe440
movq %rax, -0x30(%rbp)
leaq -0x78(%rbp), %rdi
movq %rdi, -0x170(%rbp)
callq 0xe3d0
movq -0x170(%rbp), %rdi
xorl %esi, %esi
movl %esi, -0x164(%rbp)
callq 0xe430
movl -0x164(%rbp), %eax
movq -0x38(%rbp), %rdi
addq $0x20, %rdi
movl %eax, %esi
movq %rsi, -0x160(%rbp)
callq 0xe4e0
movq -0x160(%rbp), %rsi
movq -0x38(%rbp), %rdi
addq $0x48, %rdi
callq 0xe4e0
movq -0x158(%rbp), %rcx
movq -0x150(%rbp), %rsi
movq -0x38(%rbp), %rax
movq %rcx, (%rax)
movl -0x14(%rbp), %ecx
movq -0x38(%rbp), %rax
movl %ecx, 0x18(%rax)
movq -0x38(%rbp), %rax
movl $0x0, 0x8(%rax)
movl -0x14(%rbp), %eax
movl %eax, -0x144(%rbp)
leaq -0x120(%rbp), %rdi
callq 0xe130
jmp 0xfa14
movl -0x144(%rbp), %esi
leaq -0x100(%rbp), %rdi
leaq -0x120(%rbp), %rdx
callq 0x15080
jmp 0xfa2f
leaq -0x120(%rbp), %rdi
callq 0xe1d0
cmpq $0x0, -0x20(%rbp)
jbe 0xfb96
movq -0x20(%rbp), %rsi
leaq -0x100(%rbp), %rdi
callq 0x105f0
jmp 0xfa58
jmp 0xfb96
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x128(%rbp)
movl %eax, -0x12c(%rbp)
jmp 0xfaaf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x128(%rbp)
movl %eax, -0x12c(%rbp)
leaq -0x120(%rbp), %rdi
callq 0xe1d0
jmp 0xfaaf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x128(%rbp)
movl %eax, -0x12c(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x15370
movl -0x12c(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0xfd13
movq -0x128(%rbp), %rdi
callq 0xe110
movq %rax, -0x140(%rbp)
movq 0x114d4(%rip), %rdi     # 0x20fb0
leaq 0xaba5(%rip), %rsi      # 0x1a688
callq 0xe2f0
movq %rax, -0x178(%rbp)
jmp 0xfaf1
movq -0x140(%rbp), %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movq -0x178(%rbp), %rdi
movq %rax, %rsi
callq 0xe2f0
movq %rax, -0x180(%rbp)
jmp 0xfb19
movq -0x180(%rbp), %rdi
movq 0x11469(%rip), %rsi     # 0x20f90
callq 0xe340
jmp 0xfb2e
movl $0xb, %edi
callq 0xe9c0
jmp 0xfb3a
callq 0xe550
movq -0x38(%rbp), %rdi
addq $0x20, %rdi
callq 0xe390
movq -0x38(%rbp), %rdi
addq $0x48, %rdi
callq 0xe390
leaq -0x78(%rbp), %rdi
callq 0xe570
movq -0x38(%rbp), %rax
movq %rax, -0x188(%rbp)
cmpq $0x0, %rax
je 0xfb84
movq -0x188(%rbp), %rdi
movl $0x70, %esi
callq 0xe310
movq -0x30(%rbp), %rdi
callq 0xe3b0
addq $0x1a0, %rsp            # imm = 0x1A0
popq %rbp
retq
movq -0x38(%rbp), %rax
leaq -0x100(%rbp), %rcx
movq %rcx, 0x10(%rax)
movl $0x0, -0x130(%rbp)
movl -0x130(%rbp), %eax
cmpl -0x24(%rbp), %eax
jae 0xfbf0
movq -0x30(%rbp), %rdi
movl -0x130(%rbp), %eax
shlq $0x3, %rax
addq %rax, %rdi
movq -0x38(%rbp), %rcx
leaq -0x78(%rbp), %rsi
leaq 0x486(%rip), %rdx       # 0x10060
callq 0xe620
movl -0x130(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x130(%rbp)
jmp 0xfbaf
jmp 0xfbf2
jmp 0xfbf4
movq -0x158(%rbp), %rdi
movq -0x38(%rbp), %rax
movl 0x8(%rax), %eax
movq %rax, -0x190(%rbp)
callq 0x105a0
movq %rax, %rcx
movq -0x190(%rbp), %rax
cmpq %rcx, %rax
jb 0xfc1f
jmp 0xfc5f
movq -0x158(%rbp), %rdi
movq -0x38(%rbp), %rax
movl 0x8(%rax), %eax
movq %rax, -0x198(%rbp)
callq 0x105a0
movq -0x198(%rbp), %rsi
movq %rax, %rdx
leaq -0x100(%rbp), %rdi
callq 0xff10
jmp 0xfc51
movl $0x1, %edi
callq 0xe250
jmp 0xfc5d
jmp 0xfbf2
movl $0x0, -0x134(%rbp)
movl -0x134(%rbp), %eax
cmpl -0x24(%rbp), %eax
jae 0xfca0
movq -0x30(%rbp), %rax
movl -0x134(%rbp), %ecx
movq (%rax,%rcx,8), %rdi
leaq -0x40(%rbp), %rsi
callq 0xe2d0
jmp 0xfc8d
jmp 0xfc8f
movl -0x134(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x134(%rbp)
jmp 0xfc69
movq -0x158(%rbp), %rdi
movq -0x38(%rbp), %rax
movl 0x8(%rax), %eax
movq %rax, -0x1a0(%rbp)
callq 0x105a0
movq -0x1a0(%rbp), %rsi
movq %rax, %rdx
leaq -0x100(%rbp), %rdi
callq 0xff10
jmp 0xfcd2
movq 0x1130f(%rip), %rdi     # 0x20fe8
movq 0x112b0(%rip), %rsi     # 0x20f90
callq 0xe340
jmp 0xfce7
leaq -0x100(%rbp), %rdi
callq 0x15370
jmp 0xfb3f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x128(%rbp)
movl %eax, -0x12c(%rbp)
callq 0xe550
jmp 0xfd11
jmp 0xfd13
movq -0x128(%rbp), %rdi
callq 0xe5d0
movq %rax, %rdi
callq 0x105e0
nopw (%rax,%rax)