// File: /workspace/github_cpp_makefile_star2_O2/VanAndelInstitute[P]intent/main.cpp
// Function: main
int main(int argc, char *argv[]) {
  int c, distance = 2 ;
  bool expanded = false;
  bool v2 = false;
  std::set<std::string>::iterator it_bc1;
  std::set<std::string>::iterator it_bc2;
  int format = FORMAT_V3;

  while( ( c = getopt (argc, argv, "xthvd:") ) != -1 )
  {
      switch(c)
      {
          case 'h':
              usage();
              exit(0);
          case 'v':
              std::cout << "\n  intent version " << VERSION << "\n\n";
              exit(0);
          case 'x':
              expanded = true;
              format = FORMAT_EXTENDED;
              break;
          case 'd':
              if(optarg) {
                distance = std::atoi(optarg);
              } else {
                std::cout << "The -d flag requires a value.\n\n";
              }
              break;
          case 't':
              v2 = true;
              format = FORMAT_V3;
              break;
      }
  }

  if(expanded && v2) {
    std::cout << "The -x and -t flags are mutually exclusive. Please select only 1.\n\n";
  }

  if (argv[optind] == NULL || argv[optind + 1]  == NULL) {
    usage();
    exit(0);
  }

  std::string pathR1 = argv[optind];
  std::string pathR2 = argv[optind + 1];
  std::string pathR1_out, pathR2_out;
  auto start_time = std::chrono::steady_clock::now();

  // note R1 and R2 are swapped to mimic 10X libraries
  pathR1_out = reformatFileName(pathR2, "intent_R1.fastq.gz");
  pathR2_out = reformatFileName(pathR1, "intent_R2.fastq.gz");

  std::fstream r1_fs, r2_fs; //, r1_out_fs, r2_out_fs;

  r1_fs.open(pathR1, std::ios::in);
  r2_fs.open(pathR2, std::ios::in);
  //r1_out_fs.open(pathR1_out, std::ios::out);
  //r2_out_fs.open(pathR2_out, std::ios::out);

  zstr::istream r1(r1_fs),
                r2(r2_fs);

  zstr::ofstream r1_out(pathR1_out);
  zstr::ofstream r2_out(pathR2_out);
  
  int in = 0, ok = 0, bad_w1 = 0, other = 0, shortread = 0, bad_barcode = 0, corrected = 0;
  init_stats_table();

  while(r2.peek() != EOF ) {
    in++;
    if((in % 10000) == 0)
       update_stats(start_time, in, ok, bad_w1, shortread, corrected, bad_barcode);

    std::vector<std::string> lines_r1, lines_r2;
    std::vector<int> coords;
    lines_r1 = readFour(r1);
    lines_r2 = readFour(r2);
    ParsedBarcode bc = extract_v2_barcodes(lines_r2[1], lines_r2[3], 2, true);

    if(bc.status == BC_ERROR_SHORTREAD) {
      shortread++;
    } else if(bc.status == BC_ERROR_BAD_W1) {
      bad_w1++;
    } else if(bc.status == BC_ERROR_BAD_BARCODE) {
      bad_barcode++;
    } else if(bc.status == BC_ERROR) {
      other++;
      std::cout << "An undefined error occurred processing this read: \n" << 
      lines_r2[0] << std::endl << 
      lines_r2[1] << std::endl << 
      lines_r2[2] << std::endl << 
      lines_r2[3] << std::endl; 
    } else if(bc.status == BC_OK) {
      ok++;
      if(bc.bc_fixed) {
        corrected++;
      }
      FastqRead r = format_barcode(bc, lines_r2[0], lines_r2[2], format);

      writeFour(r1_out, {r.id,
                         r.read,
                         r.direction,
                         r.quality
                        });
      writeFour(r2_out, lines_r1);

    } else {
      std::cout << "An unknown error occurred processing this read: \n" << 
      lines_r2[0] << std::endl << 
      lines_r2[1] << std::endl << 
      lines_r2[2] << std::endl << 
      lines_r2[3] << std::endl; 
      other++;
    }
  }
  r1_fs.close();
  r2_fs.close();
  //r1_out_fs.close();
  //r2_out_fs.close();

  std::cout << "\n\nComplete. Job summary: " << std::endl <<
        "Reads: " << in <<std:: endl <<
        "OK: " << ok << std::endl <<
        "Poor W1 alignment: " << bad_w1 << std::endl <<
        "Barcode or UMI too short: " << shortread <<std::endl <<
        "Barcode succesfully corrected: " << corrected << std::endl <<
        "Barcode not recognized: " << bad_barcode << std::endl;
  if(other > 0) {
        std::cout << "Unknown errors (!!): " << other << std::endl;
  }
  std::cout << std::endl;
  return(0);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1148, %rsp           # imm = 0x1148
movq %rsi, %rbx
movl %edi, %ebp
movl $0x0, 0x10(%rsp)
pushq $0x1
popq %rax
leaq 0x148e6(%rip), %r14     # 0x283b8
leaq 0x1352b(%rip), %r13     # 0x27004
movq 0x244b0(%rip), %r15     # 0x37f90
xorl %r12d, %r12d
movl %eax, 0x2c(%rsp)
movl %ebp, %edi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x60c0
cmpl $-0x1, %eax
je 0x13b3b
addl $-0x64, %eax
rorl %eax
cmpl $0xa, %eax
ja 0x13ae7
movslq (%r13,%rax,4), %rax
addq %r13, %rax
jmpq *%rax
cmpq $0x0, (%r15)
jne 0x13ae7
movq 0x2449e(%rip), %rdi     # 0x37fb8
leaq 0x148b1(%rip), %rsi     # 0x283d2
callq 0x63c0
jmp 0x13ae7
movb $0x1, %r12b
pushq $0x2
popq %rax
jmp 0x13ae3
movb $0x1, %al
movl %eax, 0x10(%rsp)
pushq $0x1
popq %rax
jmp 0x13ae3
andb 0x10(%rsp), %r12b
testb $0x1, %r12b
je 0x13b59
movq 0x2446b(%rip), %rdi     # 0x37fb8
leaq 0x1489e(%rip), %rsi     # 0x283f2
callq 0x63c0
movq 0x24460(%rip), %r14     # 0x37fc0
movslq (%r14), %rax
movq (%rbx,%rax,8), %rsi
testq %rsi, %rsi
je 0x143d3
cmpq $0x0, 0x8(%rbx,%rax,8)
je 0x143d3
leaq 0xe8(%rsp), %rdi
leaq 0x638(%rsp), %rdx
callq 0x1463a
movslq (%r14), %rax
movq 0x8(%rbx,%rax,8), %rsi
leaq 0xc8(%rsp), %rdi
leaq 0x638(%rsp), %rdx
callq 0x1463a
leaq 0xb8(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
xorl %ecx, %ecx
movb %cl, (%rax)
leaq 0x98(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb %cl, (%rax)
callq 0x6540
movq %rax, 0x68(%rsp)
leaq 0x168(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
callq 0x6580
leaq 0x1483a(%rip), %rsi     # 0x28436
leaq 0x148(%rsp), %rdi
leaq 0xe38(%rsp), %rdx
callq 0x1463a
leaq 0x638(%rsp), %rdi
leaq 0x168(%rsp), %rsi
leaq 0x148(%rsp), %rdx
callq 0x1399a
leaq 0xa8(%rsp), %rdi
leaq 0x638(%rsp), %rbx
movq %rbx, %rsi
callq 0x64d0
movq %rbx, %rdi
callq 0x6768
leaq 0x148(%rsp), %rdi
callq 0x6768
leaq 0x168(%rsp), %rdi
callq 0x6768
leaq 0x128(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
callq 0x6580
leaq 0x147c5(%rip), %rsi     # 0x28449
leaq 0x108(%rsp), %rdi
leaq 0xe38(%rsp), %rdx
callq 0x1463a
leaq 0x638(%rsp), %rdi
leaq 0x128(%rsp), %rsi
leaq 0x108(%rsp), %rdx
callq 0x1399a
leaq 0x88(%rsp), %rdi
leaq 0x638(%rsp), %rbx
movq %rbx, %rsi
callq 0x64d0
movq %rbx, %rdi
callq 0x6768
leaq 0x108(%rsp), %rdi
callq 0x6768
leaq 0x128(%rsp), %rdi
callq 0x6768
leaq 0xb58(%rsp), %rdi
callq 0x64a0
leaq 0x948(%rsp), %rdi
callq 0x64a0
leaq 0xb58(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
pushq $0x8
popq %rdx
callq 0x6570
leaq 0x948(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
pushq $0x8
popq %rdx
callq 0x6570
leaq 0x520(%rsp), %rdi
leaq 0xb58(%rsp), %rsi
callq 0x1481a
leaq 0x408(%rsp), %rdi
leaq 0x948(%rsp), %rsi
callq 0x1481a
leaq 0x638(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
pushq $0x10
popq %rdx
callq 0x148e4
leaq 0xe38(%rsp), %rdi
leaq 0x88(%rsp), %rsi
pushq $0x10
popq %rdx
callq 0x148e4
callq 0x13a07
movl $0x0, 0x10(%rsp)
leaq 0x298(%rsp), %r13
leaq 0xd68(%rsp), %r14
movl $0x0, 0x18(%rsp)
movl $0x0, 0x24(%rsp)
xorl %r15d, %r15d
movl $0x0, 0x20(%rsp)
movl $0x0, 0x1c(%rsp)
movl $0x0, 0x14(%rsp)
leaq 0x408(%rsp), %rdi
callq 0x61a0
cmpl $-0x1, %eax
je 0x141ff
movl 0x10(%rsp), %eax
incl %eax
movl %eax, 0x10(%rsp)
xorl %edx, %edx
movl $0x2710, %ecx           # imm = 0x2710
divl %ecx
testl %edx, %edx
jne 0x13e30
movl 0x1c(%rsp), %eax
movl %eax, (%rsp)
movq 0x68(%rsp), %rdi
movl 0x10(%rsp), %esi
movl 0x18(%rsp), %edx
movl 0x24(%rsp), %ecx
movl 0x20(%rsp), %r8d
movl 0x14(%rsp), %r9d
callq 0x13a2e
xorps %xmm0, %xmm0
movaps %xmm0, 0x50(%rsp)
andq $0x0, 0x60(%rsp)
movaps %xmm0, 0x30(%rsp)
andq $0x0, 0x40(%rsp)
movaps %xmm0, 0x70(%rsp)
andq $0x0, 0x80(%rsp)
leaq 0x338(%rsp), %rbx
movq %rbx, %rdi
leaq 0x520(%rsp), %rsi
callq 0x13841
leaq 0x50(%rsp), %rdi
movq %rbx, %rsi
callq 0x2235a
movq %rbx, %rdi
callq 0x146f0
movq %rbx, %rdi
leaq 0x408(%rsp), %rsi
callq 0x13841
movq %r14, %rbp
leaq 0x30(%rsp), %rdi
movq %rbx, %rsi
callq 0x2235a
movq %rbx, %rdi
callq 0x146f0
movq 0x30(%rsp), %rsi
addq $0x20, %rsi
leaq 0x1a8(%rsp), %rdi
callq 0x6580
movq 0x30(%rsp), %rsi
addq $0x60, %rsi
movq %r13, %rdi
callq 0x6580
movq %r13, %r14
leaq 0x338(%rsp), %rdi
leaq 0x1a8(%rsp), %r13
movq %r13, %rsi
movq %r14, %rdx
pushq $0x2
popq %rcx
pushq $0x1
popq %r8
callq 0x2534b
movq %r14, %rbx
movq %r14, %rdi
callq 0x6768
movq %r13, %rdi
callq 0x6768
movl 0x338(%rsp), %eax
cmpq $0x4, %rax
ja 0x14153
leaq 0x1310d(%rip), %rcx     # 0x27030
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
movq %rbx, %r13
movq %rbp, %r14
jmpq *%rax
movl %r15d, 0x4c(%rsp)
movq %r14, %rdi
movzbl 0x400(%rsp), %eax
movl %eax, 0x48(%rsp)
leaq 0x338(%rsp), %rsi
callq 0x149ba
movq 0x30(%rsp), %rsi
leaq 0x188(%rsp), %rdi
callq 0x6580
leaq 0x278(%rsp), %r13
movq 0x30(%rsp), %rsi
addq $0x40, %rsi
movq %r13, %rdi
callq 0x6580
leaq 0x2b8(%rsp), %r12
movq %r12, %rdi
movq %rbp, %r15
movq %rbp, %rsi
leaq 0x188(%rsp), %r14
movq %r14, %rdx
movq %r13, %rcx
movl 0x2c(%rsp), %r8d
callq 0x25a0d
movq %r13, %rdi
callq 0x6768
movq %r14, %rdi
callq 0x6768
movq %r15, %rdi
callq 0x14aa0
leaq 0x1f8(%rsp), %rdi
movq %r12, %rsi
callq 0x6580
leaq 0x218(%rsp), %rdi
movq %rdi, %r15
leaq 0x2d8(%rsp), %rsi
callq 0x6580
leaq 0x1c8(%rsp), %r12
leaq 0x238(%rsp), %rdi
movq %rdi, %r15
leaq 0x2f8(%rsp), %rsi
callq 0x6580
leaq 0x258(%rsp), %rdi
movq %rdi, %r15
leaq 0x318(%rsp), %rsi
callq 0x6580
leaq 0x1e0(%rsp), %r14
movq %r14, %rdi
leaq 0x1f8(%rsp), %rsi
pushq $0x4
popq %rdx
leaq 0x2b(%rsp), %rcx
callq 0x14ae4
leaq 0x638(%rsp), %rdi
movq %r14, %rsi
callq 0x13920
incl 0x18(%rsp)
movl 0x48(%rsp), %eax
addl %eax, 0x14(%rsp)
movq %r14, %rdi
callq 0x146f0
pushq $0x60
popq %r15
leaq (%rsp,%r15), %rdi
addq $0x1f8, %rdi            # imm = 0x1F8
callq 0x6768
addq $-0x20, %r15
cmpq $-0x20, %r15
jne 0x14067
movq %r12, %rdi
leaq 0x50(%rsp), %rsi
callq 0x14b1e
movl 0x4c(%rsp), %r15d
movq %rbx, %r13
movq %rbp, %r14
leaq 0xe38(%rsp), %rdi
movq %r12, %rsi
callq 0x13920
movq %r12, %rdi
callq 0x146f0
leaq 0x2b8(%rsp), %rdi
callq 0x14b72
jmp 0x141cf
incl 0x1c(%rsp)
jmp 0x141cf
incl 0x24(%rsp)
jmp 0x141cf
incl 0x20(%rsp)
jmp 0x141cf
movq 0x23ed3(%rip), %rdi     # 0x37fb8
leaq 0x14370(%rip), %rsi     # 0x2845c
callq 0x63c0
movq 0x30(%rsp), %rsi
movq %rax, %rdi
callq 0x63a0
movq %rax, %rdi
callq 0x6240
movq 0x30(%rsp), %rsi
addq $0x20, %rsi
movq %rax, %rdi
callq 0x63a0
movq %rax, %rdi
callq 0x6240
movq 0x30(%rsp), %rsi
addq $0x40, %rsi
movq %rax, %rdi
callq 0x63a0
movq %rax, %rdi
callq 0x6240
movq 0x30(%rsp), %rsi
addq $0x60, %rsi
movq %rax, %rdi
callq 0x63a0
movq %rax, %rdi
callq 0x6240
jmp 0x141cc
movq 0x23e5e(%rip), %rdi     # 0x37fb8
leaq 0x1432f(%rip), %rsi     # 0x28490
callq 0x63c0
movq %rbx, %r13
movq %rbp, %r14
movq 0x30(%rsp), %rsi
movq %rax, %rdi
callq 0x63a0
movq %rax, %rdi
callq 0x6240
movq 0x30(%rsp), %rsi
addq $0x20, %rsi
movq %rax, %rdi
callq 0x63a0
movq %rax, %rdi
callq 0x6240
movq 0x30(%rsp), %rsi
addq $0x40, %rsi
movq %rax, %rdi
callq 0x63a0
movq %rax, %rdi
callq 0x6240
movq 0x30(%rsp), %rsi
addq $0x60, %rsi
movq %rax, %rdi
callq 0x63a0
movq %rax, %rdi
callq 0x6240
incl %r15d
leaq 0x338(%rsp), %rdi
callq 0x14aa0
leaq 0x70(%rsp), %rdi
callq 0x22326
leaq 0x30(%rsp), %rdi
callq 0x146f0
leaq 0x50(%rsp), %rdi
callq 0x146f0
jmp 0x13ddc
leaq 0xb58(%rsp), %rdi
callq 0x6070
leaq 0x948(%rsp), %rdi
callq 0x6070
movq 0x23d98(%rip), %rdi     # 0x37fb8
leaq 0x1429b(%rip), %rsi     # 0x284c2
callq 0x63c0
movq %rax, %rdi
callq 0x6240
leaq 0x142a1(%rip), %rsi     # 0x284dc
movq %rax, %rdi
callq 0x63c0
movq %rax, %rdi
movl 0x10(%rsp), %esi
callq 0x6670
movq %rax, %rdi
callq 0x6240
leaq 0x14286(%rip), %rsi     # 0x284e4
movq %rax, %rdi
callq 0x63c0
movq %rax, %rdi
movl 0x18(%rsp), %esi
callq 0x6670
movq %rax, %rdi
callq 0x6240
leaq 0x14268(%rip), %rsi     # 0x284e9
movq %rax, %rdi
callq 0x63c0
movq %rax, %rdi
movl 0x24(%rsp), %esi
callq 0x6670
movq %rax, %rdi
callq 0x6240
leaq 0x14259(%rip), %rsi     # 0x284fd
movq %rax, %rdi
callq 0x63c0
movq %rax, %rdi
movl 0x20(%rsp), %esi
callq 0x6670
movq %rax, %rdi
callq 0x6240
leaq 0x14251(%rip), %rsi     # 0x28518
movq %rax, %rdi
callq 0x63c0
movq %rax, %rdi
movl 0x14(%rsp), %esi
callq 0x6670
movq %rax, %rdi
callq 0x6240
leaq 0x1424e(%rip), %rsi     # 0x28538
movq %rax, %rdi
callq 0x63c0
movq %rax, %rdi
movl 0x1c(%rsp), %esi
callq 0x6670
movq %rax, %rdi
callq 0x6240
testl %r15d, %r15d
jle 0x14331
movq 0x23ca6(%rip), %rdi     # 0x37fb8
leaq 0x14238(%rip), %rsi     # 0x28551
callq 0x63c0
movq %rax, %rdi
movl %r15d, %esi
callq 0x6670
movq %rax, %rdi
callq 0x6240
movq 0x23c80(%rip), %rdi     # 0x37fb8
callq 0x6240
leaq 0xe38(%rsp), %rdi
callq 0x14b9a
leaq 0x638(%rsp), %rdi
callq 0x14b9a
leaq 0x408(%rsp), %rdi
callq 0x14bba
leaq 0x520(%rsp), %rdi
callq 0x14bba
leaq 0x948(%rsp), %rdi
callq 0x60b0
leaq 0xb58(%rsp), %rdi
callq 0x60b0
leaq 0x88(%rsp), %rdi
callq 0x6768
leaq 0xa8(%rsp), %rdi
callq 0x6768
leaq 0xc8(%rsp), %rdi
callq 0x6768
leaq 0xe8(%rsp), %rdi
callq 0x6768
xorl %eax, %eax
addq $0x1148, %rsp           # imm = 0x1148
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x1375c
jmp 0x1440b
movq 0x23bd7(%rip), %rdi     # 0x37fb8
leaq 0x13fd7(%rip), %rsi     # 0x283bf
callq 0x63c0
leaq 0x24474(%rip), %rsi     # 0x38868
movq %rax, %rdi
callq 0x63a0
leaq 0x14030(%rip), %rsi     # 0x28433
movq %rax, %rdi
callq 0x63c0
xorl %edi, %edi
callq 0x64c0
movq %rax, %rbx
jmp 0x145bc
movq %rax, %rbx
jmp 0x145c9
movq %rax, %rbx
jmp 0x145d6
jmp 0x1448e
movq %rax, %rbx
jmp 0x145f0
jmp 0x1447e
movq %rax, %rbx
leaq 0x108(%rsp), %rdi
callq 0x6768
jmp 0x1444b
movq %rax, %rbx
leaq 0x128(%rsp), %rdi
jmp 0x14474
jmp 0x1447e
movq %rax, %rbx
leaq 0x148(%rsp), %rdi
callq 0x6768
jmp 0x1446c
movq %rax, %rbx
leaq 0x168(%rsp), %rdi
callq 0x6768
jmp 0x145fd
movq %rax, %rbx
jmp 0x145fd
movq %rax, %rbx
jmp 0x14624
movq %rax, %rbx
jmp 0x145e3
movq %rax, %rbx
jmp 0x14513
jmp 0x14581
movq %rax, %rbx
leaq 0x1c8(%rsp), %rdi
callq 0x146f0
jmp 0x1453e
jmp 0x144ec
movq %rax, %rbx
leaq 0x1e0(%rsp), %rdi
callq 0x146f0
jmp 0x144cc
movq %rax, %rbx
pushq $0x60
popq %r14
leaq (%rsp,%r14), %rdi
addq $0x1f8, %rdi            # imm = 0x1F8
callq 0x6768
addq $-0x20, %r14
cmpq $-0x20, %r14
jne 0x144d0
jmp 0x1453e
movq %rax, %rbx
jmp 0x1453e
movq %rax, %rbx
leaq 0x278(%rsp), %rdi
callq 0x6768
jmp 0x14506
movq %rax, %rbx
leaq 0x188(%rsp), %rdi
callq 0x6768
leaq 0xd68(%rsp), %rdi
callq 0x14aa0
jmp 0x14584
movq %rax, %rbx
leaq 0x1f8(%rsp), %r14
addq $-0x20, %r15
movq %r15, %rdi
callq 0x6768
cmpq %r14, %r15
jne 0x1452d
leaq 0x2b8(%rsp), %rdi
callq 0x14b72
jmp 0x14584
jmp 0x1457c
jmp 0x14553
jmp 0x14553
movq %rax, %rbx
jmp 0x14591
movq %rax, %rbx
jmp 0x1456d
movq %rax, %rbx
leaq 0x298(%rsp), %rdi
callq 0x6768
leaq 0x1a8(%rsp), %rdi
callq 0x6768
jmp 0x14591
movq %rax, %rbx
jmp 0x145af
movq %rax, %rbx
leaq 0x338(%rsp), %rdi
callq 0x14aa0
leaq 0x70(%rsp), %rdi
callq 0x22326
leaq 0x30(%rsp), %rdi
callq 0x146f0
leaq 0x50(%rsp), %rdi
callq 0x146f0
leaq 0xe38(%rsp), %rdi
callq 0x14b9a
leaq 0x638(%rsp), %rdi
callq 0x14b9a
leaq 0x408(%rsp), %rdi
callq 0x14bba
leaq 0x520(%rsp), %rdi
callq 0x14bba
leaq 0x948(%rsp), %rdi
callq 0x60b0
leaq 0xb58(%rsp), %rdi
callq 0x60b0
leaq 0x88(%rsp), %rdi
callq 0x6768
leaq 0xa8(%rsp), %rdi
callq 0x6768
leaq 0xc8(%rsp), %rdi
callq 0x6768
leaq 0xe8(%rsp), %rdi
callq 0x6768
movq %rbx, %rdi
callq 0x66a0
nop