// File: /workspace/github_cpp_makefile_star2_O2/adamnovak[P]rlcsa/display_test.cpp
// Function: main
int main(int argc, char** argv)
{
  std::cout << "RLCSA display test" << std::endl;
  if(argc < 5)
  {
    std::cout << "Usage: display_test basename weights sequences length [random_seed]" << std::endl;
    return 1;
  }
  std::cout << std::endl;

  std::cout << "Base name: " << argv[1] << std::endl;
  std::cout << "Weights: " << argv[2] << std::endl; 

  usint sequences = std::max(atoi(argv[3]), 1);
  std::cout << "Sequences: " << sequences << std::endl;

  usint seq_length = std::max(atoi(argv[4]), 1);
  std::cout << "Sequence length: " << seq_length << std::endl;

  usint seed = 0xDEADBEEF;
  if(argc > 5)
  {
    seed = atoi(argv[5]);
  }
  std::cout << "Random seed: " << seed << std::endl; 
  std::cout << std::endl;

  RLCSA rlcsa(argv[1]);
  if(!rlcsa.isOk() || !rlcsa.supportsDisplay())
  {
    std::cerr << "Error: Display is not supported!" << std::endl;
    return 2;
  }
  rlcsa.printInfo();
  rlcsa.reportSize(true);
  usint size = rlcsa.getSize();


  // Read weights and determine positions.
  weight_type* weights = new weight_type[size];
  std::ifstream weight_file(argv[2], std::ios_base::binary);
  if(!weight_file)
  {
    std::cerr << "Error: Cannot open weight file!" << std::endl;
    delete[] weights;
    return 3;
  }
  weight_file.read((char*)weights, size * sizeof(weight_type));
  weight_file.close();
  srand(seed);
  usint* positions = generatePositions(weights, size, sequences);
  delete[] weights;
  std::cout << "Generated " << sequences << " positions." << std::endl;
  std::cout << std::endl;


  // Do & measure the actual work.
  uchar* buffer = new uchar[seq_length];
  double start = readTimer();
  for(usint i = 0; i < sequences; i++)
  {
    rlcsa.display(0, pair_type(positions[i], positions[i] + seq_length - 1), buffer);
  }
  double time = readTimer() - start;
  std::cout << "Total time: " << time << " seconds." << std::endl;
  std::cout << std::endl;


  delete[] buffer;
  delete[] positions;
  return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa58, %rsp            # imm = 0xA58
movq %rsi, %r15
movl %edi, %r12d
movq 0x190c6(%rip), %rdi     # 0x1cfd0
leaq 0xf199(%rip), %rsi      # 0x130aa
callq 0x3210
movq %rax, %rdi
callq 0x3100
pushq $0x1
popq %rbx
cmpl $0x4, %r12d
jg 0x3f47
movq 0x190a2(%rip), %rdi     # 0x1cfd0
leaq 0xf188(%rip), %rsi      # 0x130bd
callq 0x3210
movq %rax, %rdi
callq 0x3100
jmp 0x427d
movq 0x19082(%rip), %r13     # 0x1cfd0
movq %r13, %rdi
callq 0x3100
leaq 0xf1a4(%rip), %rsi      # 0x13101
movq %r13, %rdi
callq 0x3210
movq 0x8(%r15), %rsi
movq %rax, %rdi
callq 0x3210
movq %rax, %rdi
callq 0x3100
leaq 0xf18d(%rip), %rsi      # 0x1310d
movq %r13, %rdi
callq 0x3210
movq 0x10(%r15), %rsi
movq %rax, %rdi
callq 0x3210
movq %rax, %rdi
callq 0x3100
movq 0x18(%r15), %rdi
callq 0x3360
movl %eax, %r14d
cmpl $0x2, %eax
cmovll %ebx, %r14d
leaq 0xf161(%rip), %rsi      # 0x13117
movq %r13, %rdi
callq 0x3210
movq %rax, %rdi
movq %r14, %rsi
callq 0x3160
movq %rax, %rdi
callq 0x3100
movq 0x20(%r15), %rdi
callq 0x3360
cmpl $0x2, %eax
cmovgel %eax, %ebx
leaq 0xf13c(%rip), %rsi      # 0x13123
movq %r13, %rdi
callq 0x3210
movq %rax, %rdi
movq %rbx, %rsi
callq 0x3160
movq %rax, %rdi
callq 0x3100
movl $0xdeadbeef, %ebp       # imm = 0xDEADBEEF
cmpl $0x5, %r12d
je 0x4018
movq 0x28(%r15), %rdi
callq 0x3360
movl %eax, %ebp
movq 0x18fb1(%rip), %r12     # 0x1cfd0
leaq 0xf10f(%rip), %rsi      # 0x13135
movq %r12, %rdi
callq 0x3210
movl %ebp, %esi
movq %rax, %rdi
callq 0x3160
movq %rax, %rdi
callq 0x3100
movq %r12, %rdi
callq 0x3100
movq 0x8(%r15), %rsi
leaq 0x20(%rsp), %rdi
leaq 0xf(%rsp), %rdx
callq 0x44f2
leaq 0x228(%rsp), %rdi
leaq 0x20(%rsp), %rsi
xorl %edx, %edx
callq 0x4654
leaq 0x20(%rsp), %rdi
callq 0x3478
cmpb $0x1, 0x228(%rsp)
jne 0x4115
cmpb $0x0, 0xa41(%rsp)
je 0x4115
leaq 0x228(%rsp), %rdi
callq 0x7260
leaq 0x228(%rsp), %rdi
pushq $0x1
popq %rsi
callq 0x709c
movl 0x22c(%rsp), %eax
movq %rax, 0x10(%rsp)
leaq (,%rax,4), %r13
movq %r13, %rdi
callq 0x3030
movq %rax, %r12
movq 0x10(%r15), %rsi
leaq 0x20(%rsp), %rdi
pushq $0x4
popq %rdx
callq 0x3430
movq 0x20(%rsp), %rax
movq -0x18(%rax), %rax
testb $0x5, 0x40(%rsp,%rax)
je 0x4138
movq 0x18ef7(%rip), %rdi     # 0x1cff0
leaq 0xf064(%rip), %rsi      # 0x13164
callq 0x3210
movq %rax, %rdi
callq 0x3100
pushq $0x3
popq %rbx
jmp 0x425e
movq 0x18ed4(%rip), %rdi     # 0x1cff0
leaq 0xf020(%rip), %rsi      # 0x13143
callq 0x3210
movq %rax, %rdi
callq 0x3100
pushq $0x2
popq %rbx
jmp 0x4270
leaq 0x20(%rsp), %rdi
movq %r12, %rsi
movq %r13, %rdx
callq 0x3290
leaq 0x20(%rsp), %rdi
callq 0x3080
movl %ebp, %edi
callq 0x3200
movq %r12, %rdi
movq 0x10(%rsp), %rsi
movl %r14d, %edx
callq 0x42da
movq %rax, %r15
movq %r12, %rdi
callq 0x32b0
movq 0x18e55(%rip), %rdi     # 0x1cfd0
leaq 0xf002(%rip), %rsi      # 0x13184
callq 0x3210
movq %rax, %rdi
movq %r14, %rsi
callq 0x3160
leaq 0xeff6(%rip), %rsi      # 0x1318f
movq %rax, %rdi
callq 0x3210
movq %rax, %rdi
callq 0x3100
movq 0x18e20(%rip), %rdi     # 0x1cfd0
callq 0x3100
movq %rbx, %rdi
callq 0x3030
movq %rax, %r12
callq 0x10b84
movsd %xmm0, 0x10(%rsp)
decl %ebx
xorl %ebp, %ebp
leaq 0x228(%rsp), %r13
cmpq %rbp, %r14
je 0x41fc
movl (%r15,%rbp,4), %eax
leal (%rbx,%rax), %edx
shlq $0x20, %rdx
orq %rax, %rdx
movq %r13, %rdi
xorl %esi, %esi
movq %r12, %rcx
callq 0x691a
incq %rbp
jmp 0x41d7
callq 0x10b84
movsd %xmm0, 0x18(%rsp)
movq 0x18dc2(%rip), %rdi     # 0x1cfd0
leaq 0xef86(%rip), %rsi      # 0x1319b
callq 0x3210
movsd 0x18(%rsp), %xmm0
subsd 0x10(%rsp), %xmm0
movq %rax, %rdi
callq 0x3390
leaq 0xef73(%rip), %rsi      # 0x131a8
movq %rax, %rdi
callq 0x3210
movq %rax, %rdi
callq 0x3100
movq 0x18d84(%rip), %rdi     # 0x1cfd0
callq 0x3100
movq %r12, %rdi
callq 0x32b0
xorl %ebx, %ebx
movq %r15, %r12
movq %r12, %rdi
callq 0x32b0
leaq 0x20(%rsp), %rdi
callq 0x3090
leaq 0x228(%rsp), %rdi
callq 0x58d6
movl %ebx, %eax
addq $0xa58, %rsp            # imm = 0xA58
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x42b8
jmp 0x42b8
jmp 0x42b3
jmp 0x42b3
jmp 0x42b8
jmp 0x42b8
jmp 0x42b8
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x3478
jmp 0x42d2
movq %rax, %rbx
jmp 0x42d2
movq %rax, %rbx
jmp 0x42c5
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x3090
leaq 0x228(%rsp), %rdi
callq 0x58d6
movq %rbx, %rdi
callq 0x3410