// File: karel-brinda[P]ococo/src/params.cpp
// Function: ococo::params_t::parse_commandline(int, char const**)
void ococo::params_t::parse_commandline(int argc, const char **argv) {
    /* Parse cmd parameters */
    std::stringstream cmd;
    for (int32_t i = 0; i < argc; i++) {
        cmd << argv[i];
        if (i != argc - 1) {
            cmd << " ";
        }
    }
    command=cmd.str();


    if (argc == 1) {
        print_help();
        exit(1);
    }

    const struct option lopts[] = {
        {"version", no_argument, nullptr, 'v'},
        {"help", no_argument, nullptr, 'h'},
        //
        {"input", required_argument, nullptr, 'i'},
        {"fasta-ref", required_argument, nullptr, 'f'},
        {"stats-in", required_argument, nullptr, 's'},
        //
        {"fasta-cons", required_argument, nullptr, 'F'},
        {"stats-out", required_argument, nullptr, 'S'},
        {"vcf-cons", required_argument, nullptr, 'V'},
        {"pileup", required_argument, nullptr, 'P'},
        {"log", required_argument, nullptr, 'L'},
        {"verbose", no_argument, nullptr, 'W'},
        //
        {"counters", required_argument, nullptr, 'x'},
        {"mode", required_argument, nullptr, 'm'},
        {"strategy", required_argument, nullptr, 't'},
        {"min-MQ", required_argument, nullptr, 'q'},
        {"min-BQ", required_argument, nullptr, 'Q'},
        {"ref-weight", required_argument, nullptr, 'w'},
        {"min-cov", required_argument, nullptr, 'c'},
        {"min-coverage", required_argument, nullptr, 'c'},  // deprec
        {"maj-thres", required_argument, nullptr, 'M'},
        {"majority-threshold", required_argument, nullptr, 'M'},  // deprec
        //
        {nullptr, 0, nullptr, 0}};

    int c;
    using std::string;
    while ((c = getopt_long(argc, (char *const *)argv,
                            "vhi:f:s:F:S:V:P:L:W:x:m:t:q:Q:w:c:M:", lopts,
                            nullptr)) >= 0) {
        switch (c) {
            case 'v': {
                print_version();
                exit(0);
                break;
            }
            case 'h': {
                print_help();
                exit(0);
                break;
            }
            case 'i': {
                sam_fn = optarg;
                break;
            }
            case 'f': {
                fasta_in_fn = optarg;
                break;
            }
            case 's': {
                stats_in_fn = optarg;
                break;
            }
            case 'F': {
                fasta_out_fn = optarg;
                break;
            }
            case 'S': {
                stats_out_fn = optarg;
                break;
            }
            case 'V': {
                vcf_fn = optarg;
                break;
            }
            case 'P': {
                pileup_fn = optarg;
                break;
            }
            case 'L': {
                log_fn = optarg;
                break;
            }
            case 'W': {
                verbose = true;
                break;
            }
            case 'x': {
                counters_str = optarg;

                if (counters_str.compare("ococo16") == 0) {
                    counter_configuration = OCOCO16;
                    counters_str_descr =
                        "ococo16 (16 bits per position, 3bits per nucleotide "
                        "counter)";
                } else if (counters_str.compare("ococo32") == 0) {
                    counter_configuration = OCOCO32;
                    counters_str_descr =
                        "ococo32 (32 bits per position, 7bits per nucleotide "
                        "counter)";
                } else if (counters_str.compare("ococo64") == 0) {
                    counter_configuration = OCOCO64;
                    counters_str_descr =
                        "ococo64 (64 bits per position, 15bits per nucleotide "
                        "counter)";
                } else {
                    ococo::error(
                        "Unknown counter configuration '%s'. Possible modes "
                        "are 'ococo16', 'ococo32', and 'ococo64'.\n",
                        counters_str.c_str());
                    exit(1);
                }

                break;
            }
            case 'm': {
                mode_str = optarg;

                if (mode_str.compare("batch") == 0) {
                    mode = ococo::mode_t::BATCH;
                } else if (mode_str.compare("real-time") == 0) {
                    mode = ococo::mode_t::REALTIME;
                } else {
                    ococo::error(
                        "Unknown mode '%s'. Possible modes are 'batch' and "
                        "'real-time'.\n",
                        mode_str.c_str());
                    exit(1);
                }

                break;
            }
            case 't': {
                strategy_str = optarg;

                if (strategy_str.compare("stochastic") == 0) {
                    strategy = ococo::strategy_t::STOCHASTIC;
                } else if (strategy_str.compare("no-updates") == 0) {
                    strategy = ococo::strategy_t::NO_UPDATES;
                } else if (strategy_str.compare("majority") == 0) {
                    strategy = ococo::strategy_t::MAJORITY;
                } else {
                    ococo::error(
                        "Unknown strategy '%s'. Possible strategies are "
                        "'majority', 'stochastic', and 'no-updates'.\n",
                        strategy_str.c_str());
                    exit(1);
                }

                break;
            }
            case 'q': {
                min_mapq = atoi(optarg);
                break;
            }
            case 'Q': {
                min_baseq = atoi(optarg);
                break;
            }
            case 'w': {
                init_ref_weight = atoi(optarg);
                break;
            }
            case 'c': {
                min_coverage = atoi(optarg);
                break;
            }
            case 'M': {
                majority_threshold = atof(optarg);
                break;
            }
            case '?': {
                ococo::error("Unknown error");
                exit(1);
                break;
            }
        }
    }
    if (sam_fn.size()==0){
        ococo::error("SAM/BAM file must be specified (option '-i').\n");
        exit(1);
    }

    if(pileup_fn.size()!=0 && pileup_fn.compare(vcf_fn)==0){
        ococo::error("Pileup and VCF files cannot be the same (both currently '%s').\n", pileup_fn.c_str());
        exit(1);
    }

    ococo::info("Ococo starting: %s\n", counters_str_descr.c_str());
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x4c0, %rsp            # imm = 0x4C0
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x4b0(%rbp)
leaq -0x1a0(%rbp), %rdi
callq 0x43b0
movl $0x0, -0x1a4(%rbp)
movl -0x1a4(%rbp), %eax
cmpl -0xc(%rbp), %eax
jge 0xfd2f
leaq -0x190(%rbp), %rdi
movq -0x18(%rbp), %rax
movslq -0x1a4(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
callq 0x4580
jmp 0xfccf
movl -0x1a4(%rbp), %eax
movl -0xc(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
je 0xfd19
leaq -0x190(%rbp), %rdi
leaq 0x69fd4(%rip), %rsi     # 0x79cc1
callq 0x4580
jmp 0xfcf4
jmp 0xfd19
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1b0(%rbp)
movl %eax, -0x1b4(%rbp)
leaq -0x1a0(%rbp), %rdi
callq 0x4410
jmp 0x103ad
jmp 0xfd1b
movl -0x1a4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1a4(%rbp)
jmp 0xfca7
leaq -0x1d8(%rbp), %rdi
leaq -0x1a0(%rbp), %rsi
callq 0x4570
jmp 0xfd44
movq -0x4b0(%rbp), %rdi
addq $0x8, %rdi
leaq -0x1d8(%rbp), %rsi
callq 0x46f0
leaq -0x1d8(%rbp), %rdi
callq 0x4340
cmpl $0x1, -0xc(%rbp)
jne 0xfd85
movq -0x4b0(%rbp), %rdi
callq 0x10610
jmp 0xfd7b
movl $0x1, %edi
callq 0x46c0
leaq -0x4a0(%rbp), %rdi
leaq 0x79c2d(%rip), %rsi     # 0x899c0
movl $0x2c0, %edx            # imm = 0x2C0
callq 0x4460
movl -0xc(%rbp), %edi
movq -0x18(%rbp), %rsi
leaq -0x4a0(%rbp), %rcx
leaq 0x6a9ee(%rip), %rdx     # 0x7a7a0
xorl %eax, %eax
movl %eax, %r8d
callq 0x49b0
movl %eax, -0x4a4(%rbp)
cmpl $0x0, %eax
jl 0x102cc
movl -0x4a4(%rbp), %eax
addl $-0x3f, %eax
movl %eax, %ecx
movq %rcx, -0x4b8(%rbp)
subl $0x39, %eax
ja 0x102c7
movq -0x4b8(%rbp), %rax
leaq 0x69eec(%rip), %rcx     # 0x79ce0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
callq 0xf350
jmp 0xfe04
xorl %edi, %edi
callq 0x46c0
movq -0x4b0(%rbp), %rdi
callq 0x10610
jmp 0xfe19
xorl %edi, %edi
callq 0x46c0
movq -0x4b0(%rbp), %rdi
movq 0x7a18a(%rip), %rax     # 0x89fb8
movq (%rax), %rsi
addq $0x78, %rdi
callq 0x47c0
jmp 0xfe3c
jmp 0x102c7
movq -0x4b0(%rbp), %rdi
movq 0x7a169(%rip), %rax     # 0x89fb8
movq (%rax), %rsi
addq $0x98, %rdi
callq 0x47c0
jmp 0xfe60
jmp 0x102c7
movq -0x4b0(%rbp), %rdi
movq 0x7a145(%rip), %rax     # 0x89fb8
movq (%rax), %rsi
addq $0xb8, %rdi
callq 0x47c0
jmp 0xfe84
jmp 0x102c7
movq -0x4b0(%rbp), %rdi
movq 0x7a121(%rip), %rax     # 0x89fb8
movq (%rax), %rsi
addq $0x100, %rdi            # imm = 0x100
callq 0x47c0
jmp 0xfea8
jmp 0x102c7
movq -0x4b0(%rbp), %rdi
movq 0x7a0fd(%rip), %rax     # 0x89fb8
movq (%rax), %rsi
addq $0x120, %rdi            # imm = 0x120
callq 0x47c0
jmp 0xfecc
jmp 0x102c7
movq -0x4b0(%rbp), %rdi
movq 0x7a0d9(%rip), %rax     # 0x89fb8
movq (%rax), %rsi
addq $0xe0, %rdi
callq 0x47c0
jmp 0xfef0
jmp 0x102c7
movq -0x4b0(%rbp), %rdi
movq 0x7a0b5(%rip), %rax     # 0x89fb8
movq (%rax), %rsi
addq $0x140, %rdi            # imm = 0x140
callq 0x47c0
jmp 0xff14
jmp 0x102c7
movq -0x4b0(%rbp), %rdi
movq 0x7a091(%rip), %rax     # 0x89fb8
movq (%rax), %rsi
addq $0x160, %rdi            # imm = 0x160
callq 0x47c0
jmp 0xff38
jmp 0x102c7
movq -0x4b0(%rbp), %rax
movb $0x1, 0xd8(%rax)
jmp 0x102c7
movq -0x4b0(%rbp), %rdi
movq 0x7a05a(%rip), %rax     # 0x89fb8
movq (%rax), %rsi
addq $0x30, %rdi
callq 0x47c0
jmp 0xff6c
movq -0x4b0(%rbp), %rdi
addq $0x30, %rdi
leaq 0x6a847(%rip), %rsi     # 0x7a7c5
callq 0x4150
cmpl $0x0, %eax
jne 0xffad
movq -0x4b0(%rbp), %rdi
movl $0x0, 0x28(%rdi)
addq $0x50, %rdi
leaq 0x6a82c(%rip), %rsi     # 0x7a7cd
callq 0x47c0
jmp 0xffa8
jmp 0x1005a
movq -0x4b0(%rbp), %rdi
addq $0x30, %rdi
leaq 0x69f41(%rip), %rsi     # 0x79f00
callq 0x4150
cmpl $0x0, %eax
jne 0xffeb
movq -0x4b0(%rbp), %rdi
movl $0x1, 0x28(%rdi)
addq $0x50, %rdi
leaq 0x6a828(%rip), %rsi     # 0x7a80a
callq 0x47c0
jmp 0xffe9
jmp 0x10058
movq -0x4b0(%rbp), %rdi
addq $0x30, %rdi
leaq 0x6a84a(%rip), %rsi     # 0x7a847
callq 0x4150
cmpl $0x0, %eax
jne 0x10029
movq -0x4b0(%rbp), %rdi
movl $0x2, 0x28(%rdi)
addq $0x50, %rdi
leaq 0x6a82f(%rip), %rsi     # 0x7a84f
callq 0x47c0
jmp 0x10027
jmp 0x10056
movq -0x4b0(%rbp), %rdi
addq $0x30, %rdi
callq 0x4200
movq %rax, %rsi
leaq 0x6a84a(%rip), %rdi     # 0x7a88d
xorl %eax, %eax
callq 0xf460
jmp 0x1004c
movl $0x1, %edi
callq 0x46c0
jmp 0x10058
jmp 0x1005a
jmp 0x102c7
movq -0x4b0(%rbp), %rdi
movq 0x79f4b(%rip), %rax     # 0x89fb8
movq (%rax), %rsi
addq $0x1e8, %rdi            # imm = 0x1E8
callq 0x47c0
jmp 0x1007e
movq -0x4b0(%rbp), %rdi
addq $0x1e8, %rdi            # imm = 0x1E8
leaq 0x69e75(%rip), %rsi     # 0x79f08
callq 0x4150
cmpl $0x0, %eax
jne 0x100b0
movq -0x4b0(%rbp), %rax
movl $0x0, 0x1a8(%rax)
jmp 0x10114
movq -0x4b0(%rbp), %rdi
addq $0x1e8, %rdi            # imm = 0x1E8
leaq 0x6a825(%rip), %rsi     # 0x7a8ea
callq 0x4150
cmpl $0x0, %eax
jne 0x100e2
movq -0x4b0(%rbp), %rax
movl $0x1, 0x1a8(%rax)
jmp 0x10112
movq -0x4b0(%rbp), %rdi
addq $0x1e8, %rdi            # imm = 0x1E8
callq 0x4200
movq %rax, %rsi
leaq 0x6a7f5(%rip), %rdi     # 0x7a8f4
xorl %eax, %eax
callq 0xf460
jmp 0x10108
movl $0x1, %edi
callq 0x46c0
jmp 0x10114
jmp 0x102c7
movq -0x4b0(%rbp), %rdi
movq 0x79e91(%rip), %rax     # 0x89fb8
movq (%rax), %rsi
addq $0x1c8, %rdi            # imm = 0x1C8
callq 0x47c0
jmp 0x10138
movq -0x4b0(%rbp), %rdi
addq $0x1c8, %rdi            # imm = 0x1C8
leaq 0x6a7e7(%rip), %rsi     # 0x7a934
callq 0x4150
cmpl $0x0, %eax
jne 0x1016d
movq -0x4b0(%rbp), %rax
movl $0x1, 0x1ac(%rax)
jmp 0x10205
movq -0x4b0(%rbp), %rdi
addq $0x1c8, %rdi            # imm = 0x1C8
leaq 0x6a7bd(%rip), %rsi     # 0x7a93f
callq 0x4150
cmpl $0x0, %eax
jne 0x1019f
movq -0x4b0(%rbp), %rax
movl $0x0, 0x1ac(%rax)
jmp 0x10203
movq -0x4b0(%rbp), %rdi
addq $0x1c8, %rdi            # imm = 0x1C8
leaq 0x69d5a(%rip), %rsi     # 0x79f0e
callq 0x4150
cmpl $0x0, %eax
jne 0x101d1
movq -0x4b0(%rbp), %rax
movl $0x3, 0x1ac(%rax)
jmp 0x10201
movq -0x4b0(%rbp), %rdi
addq $0x1c8, %rdi            # imm = 0x1C8
callq 0x4200
movq %rax, %rsi
leaq 0x6a75c(%rip), %rdi     # 0x7a94a
xorl %eax, %eax
callq 0xf460
jmp 0x101f7
movl $0x1, %edi
callq 0x46c0
jmp 0x10203
jmp 0x10205
jmp 0x102c7
movq 0x79da7(%rip), %rax     # 0x89fb8
movq (%rax), %rdi
callq 0x4910
movl %eax, %ecx
movq -0x4b0(%rbp), %rax
movl %ecx, 0x1b0(%rax)
jmp 0x102c7
movq 0x79d84(%rip), %rax     # 0x89fb8
movq (%rax), %rdi
callq 0x4910
movl %eax, %ecx
movq -0x4b0(%rbp), %rax
movl %ecx, 0x1b4(%rax)
jmp 0x102c7
movq 0x79d64(%rip), %rax     # 0x89fb8
movq (%rax), %rdi
callq 0x4910
movl %eax, %ecx
movq -0x4b0(%rbp), %rax
movl %ecx, 0x1b8(%rax)
jmp 0x102c7
movq 0x79d44(%rip), %rax     # 0x89fb8
movq (%rax), %rdi
callq 0x4910
movl %eax, %ecx
movq -0x4b0(%rbp), %rax
movl %ecx, 0x1bc(%rax)
jmp 0x102c7
movq 0x79d24(%rip), %rax     # 0x89fb8
movq (%rax), %rdi
callq 0x4720
movq -0x4b0(%rbp), %rax
movsd %xmm0, 0x1c0(%rax)
jmp 0x102c7
leaq 0x6a6f2(%rip), %rdi     # 0x7a9a6
xorl %eax, %eax
callq 0xf460
jmp 0x102bd
movl $0x1, %edi
callq 0x46c0
jmp 0xfd9d
movq -0x4b0(%rbp), %rdi
addq $0x78, %rdi
callq 0x43a0
cmpq $0x0, %rax
jne 0x102fc
leaq 0x6a6cb(%rip), %rdi     # 0x7a9b4
xorl %eax, %eax
callq 0xf460
jmp 0x102f2
movl $0x1, %edi
callq 0x46c0
movq -0x4b0(%rbp), %rdi
addq $0x140, %rdi            # imm = 0x140
callq 0x43a0
cmpq $0x0, %rax
je 0x10375
movq -0x4b0(%rbp), %rsi
movq %rsi, %rdi
addq $0x140, %rdi            # imm = 0x140
addq $0xe0, %rsi
callq 0x4050
movl %eax, -0x4bc(%rbp)
jmp 0x1033a
movl -0x4bc(%rbp), %eax
cmpl $0x0, %eax
jne 0x10375
movq -0x4b0(%rbp), %rdi
addq $0x140, %rdi            # imm = 0x140
callq 0x4200
movq %rax, %rsi
leaq 0x6a681(%rip), %rdi     # 0x7a9e3
xorl %eax, %eax
callq 0xf460
jmp 0x1036b
movl $0x1, %edi
callq 0x46c0
movq -0x4b0(%rbp), %rdi
addq $0x50, %rdi
callq 0x4200
movq %rax, %rsi
leaq 0x6a694(%rip), %rdi     # 0x7aa23
xorl %eax, %eax
callq 0xf5e0
jmp 0x10398
leaq -0x1a0(%rbp), %rdi
callq 0x4410
addq $0x4c0, %rsp            # imm = 0x4C0
popq %rbp
retq
movq -0x1b0(%rbp), %rdi
callq 0x4a30
nopl (%rax)