// File: shreyas-gopalakrishna[P]Concurrent-Skip-list/main.cpp
// Function: main
int main(int argc, char *argv[]){

    static struct option long_options[] = {
        {"name", no_argument, NULL, 'n'},
        {"operation", required_argument, NULL, 'o'},
        {"help", no_argument, NULL, 'h'},
        {0, 0, 0, 0}
    };

    //Variables for options
    bool name = false;
    int max_number = -1;
    string operation = "";
    bool help = false;

    while (true) {
        int option_index = 0;
        int flag_char = getopt_long(argc, argv, "i:t:", long_options, &option_index);
        if (flag_char == -1) {
          break;
        }

        switch (flag_char) {
            case 'n':
                name = true;
                break;
            case 'o':
                operation = std::string(optarg);
                break;
            case 'h':
                help = true;
                break;
            case 't':
                num_threads = stoi(optarg);
                break;
            case 'i':
                max_number = stoi(optarg);
                break;
            case '?':
                break;
            default:
                exit(EXIT_FAILURE);
        }
    }

    if(name){
        cout << "\nShreyas Gopalakrishna\n";
    }

    if(help){
        show_usage();
    }

	if(argc > 2){
	    if(operation == "" || max_number <= 0 || num_threads < 1 ){
	        show_usage();
	    }else{

            generate_input(max_number);
            skiplist = SkipList(numbers_insert.size(), 0.5);

	        if(operation == "separate"){
                concurrent_skiplist_seperate();
	        }
	        else if (operation == "combined"){
                concurrent_skiplist_combined();
	        }else{
	            cout << "Invalid operation type \n";
	            show_usage();
	        }
	    }
    }else{
        show_usage();
    }
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x130, %rsp            # imm = 0x130
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movb $0x0, -0x11(%rbp)
movl $0xffffffff, -0x18(%rbp) # imm = 0xFFFFFFFF
leaq -0x39(%rbp), %rdi
movq %rdi, -0xe8(%rbp)
callq 0x3400
movq -0xe8(%rbp), %rdx
leaq 0xa287(%rip), %rsi      # 0xf0e9
leaq -0x38(%rbp), %rdi
callq 0x55c0
jmp 0x4e6d
leaq -0x39(%rbp), %rdi
callq 0x32a0
movb $0x0, -0x4d(%rbp)
jmp 0x4e7c
movl $0x0, -0x54(%rbp)
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq 0xa7ec(%rip), %rdx      # 0xf67d
leaq 0x123b8(%rip), %rcx     # 0x17250
leaq -0x54(%rbp), %r8
callq 0x33b0
movl %eax, -0x58(%rbp)
cmpl $-0x1, -0x58(%rbp)
jne 0x4ec9
jmp 0x510a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x39(%rbp), %rdi
callq 0x32a0
jmp 0x5285
movl -0x58(%rbp), %eax
addl $-0x3f, %eax
movl %eax, %ecx
movq %rcx, -0xf0(%rbp)
subl $0x35, %eax
ja 0x50fb
movq -0xf0(%rbp), %rax
leaq 0xa119(%rip), %rcx      # 0xf008
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movb $0x1, -0x11(%rbp)
jmp 0x5105
movq 0x120a8(%rip), %rax     # 0x16fb0
movq (%rax), %rax
movq %rax, -0x100(%rbp)
leaq -0x79(%rbp), %rdi
movq %rdi, -0xf8(%rbp)
callq 0x3400
movq -0x100(%rbp), %rsi
movq -0xf8(%rbp), %rdx
leaq -0x78(%rbp), %rdi
callq 0x55c0
jmp 0x4f3b
leaq -0x38(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x3300
leaq -0x78(%rbp), %rdi
callq 0x3170
leaq -0x79(%rbp), %rdi
callq 0x32a0
jmp 0x5105
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x79(%rbp), %rdi
callq 0x32a0
jmp 0x527c
movb $0x1, -0x4d(%rbp)
jmp 0x5105
movq 0x12027(%rip), %rax     # 0x16fb0
movq (%rax), %rax
movq %rax, -0x110(%rbp)
leaq -0xa1(%rbp), %rdi
movq %rdi, -0x108(%rbp)
callq 0x3400
movq -0x110(%rbp), %rsi
movq -0x108(%rbp), %rdx
leaq -0xa0(%rbp), %rdi
callq 0x55c0
jmp 0x4fc2
xorl %eax, %eax
movl %eax, %esi
leaq -0xa0(%rbp), %rdi
movl $0xa, %edx
callq 0x5d50
movl %eax, -0x114(%rbp)
jmp 0x4fdf
movl -0x114(%rbp), %eax
cltq
movq %rax, 0x12252(%rip)     # 0x17240
leaq -0xa0(%rbp), %rdi
callq 0x3170
leaq -0xa1(%rbp), %rdi
callq 0x32a0
jmp 0x5105
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x5031
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0xa0(%rbp), %rdi
callq 0x3170
leaq -0xa1(%rbp), %rdi
callq 0x32a0
jmp 0x527c
movq 0x11f67(%rip), %rax     # 0x16fb0
movq (%rax), %rax
movq %rax, -0x128(%rbp)
leaq -0xc9(%rbp), %rdi
movq %rdi, -0x120(%rbp)
callq 0x3400
movq -0x128(%rbp), %rsi
movq -0x120(%rbp), %rdx
leaq -0xc8(%rbp), %rdi
callq 0x55c0
jmp 0x5082
xorl %eax, %eax
movl %eax, %esi
leaq -0xc8(%rbp), %rdi
movl $0xa, %edx
callq 0x5d50
movl %eax, -0x12c(%rbp)
jmp 0x509f
movl -0x12c(%rbp), %eax
movl %eax, -0x18(%rbp)
leaq -0xc8(%rbp), %rdi
callq 0x3170
leaq -0xc9(%rbp), %rdi
callq 0x32a0
jmp 0x5105
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x50e8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0xc8(%rbp), %rdi
callq 0x3170
leaq -0xc9(%rbp), %rdi
callq 0x32a0
jmp 0x527c
jmp 0x5105
movl $0x1, %edi
callq 0x32f0
jmp 0x4e7a
testb $0x1, -0x11(%rbp)
je 0x5138
movq 0x11eb1(%rip), %rdi     # 0x16fc8
leaq 0xa564(%rip), %rsi      # 0xf682
callq 0x3240
jmp 0x5125
jmp 0x5138
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x527c
testb $0x1, -0x4d(%rbp)
je 0x5147
callq 0x36f0
jmp 0x5145
jmp 0x5147
cmpl $0x2, -0x8(%rbp)
jle 0x5257
leaq 0x9f91(%rip), %rsi      # 0xf0e9
leaq -0x38(%rbp), %rdi
callq 0x5d90
movb %al, -0x12d(%rbp)
jmp 0x5169
movb -0x12d(%rbp), %al
testb $0x1, %al
jne 0x5185
jmp 0x5175
cmpl $0x0, -0x18(%rbp)
jle 0x5185
cmpq $0x1, 0x120bd(%rip)     # 0x17240
jae 0x5191
callq 0x36f0
jmp 0x518c
jmp 0x5255
movl -0x18(%rbp), %edi
callq 0x37f0
jmp 0x519b
leaq 0x1215e(%rip), %rdi     # 0x17300
callq 0x5400
movl %eax, %esi
leaq -0xe0(%rbp), %rdi
movss 0x9e4c(%rip), %xmm0     # 0xf004
callq 0xab80
jmp 0x51bf
movups -0xe0(%rbp), %xmm0
movups %xmm0, 0x12123(%rip)    # 0x172f0
leaq -0xe0(%rbp), %rdi
callq 0xc790
leaq 0xa4ba(%rip), %rsi      # 0xf69a
leaq -0x38(%rbp), %rdi
callq 0x5d90
movb %al, -0x12e(%rbp)
jmp 0x51f1
movb -0x12e(%rbp), %al
testb $0x1, %al
jne 0x51fd
jmp 0x5206
callq 0x3f40
jmp 0x5204
jmp 0x5253
leaq 0xa496(%rip), %rsi      # 0xf6a3
leaq -0x38(%rbp), %rdi
callq 0x5d90
movb %al, -0x12f(%rbp)
jmp 0x521e
movb -0x12f(%rbp), %al
testb $0x1, %al
jne 0x522a
jmp 0x5233
callq 0x4b30
jmp 0x5231
jmp 0x5251
movq 0x11d8e(%rip), %rdi     # 0x16fc8
leaq 0xa46b(%rip), %rsi      # 0xf6ac
callq 0x3240
jmp 0x5248
callq 0x36f0
jmp 0x524f
jmp 0x5251
jmp 0x5253
jmp 0x5255
jmp 0x5260
callq 0x36f0
jmp 0x525e
jmp 0x5260
movl $0x0, -0x4(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x3170
movl -0x4(%rbp), %eax
addq $0x130, %rsp            # imm = 0x130
popq %rbp
retq
leaq -0x38(%rbp), %rdi
callq 0x3170
movq -0x48(%rbp), %rdi
callq 0x33f0
nop