// File: /workspace/github_cpp_makefile_star2_O2/jpbalarini[P]otsus/./framework/CInspector.cpp
// Function: CInspector::process_input(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, CFramework*)
int CInspector::process_input(string input, CFramework *fw) {
  vector<string> tokens;

  int num_tokens = read_tokens(&tokens, input);
  if (num_tokens == 0) return INSPECTOR_OK; // just pressed <ENTER>

  string command = tokens[0];
  if (!check_command_arguments(command, num_tokens)) {
    return INSPECTOR_ERR_BAD_ARGUMENTS;
  }

  if (command == "l" || command == "list") {
    fw->print_matrix_list();
    return INSPECTOR_OK;
  }

  if (command == "u" || command == "use") {
    if (tokens.size() != 2) {
      return INSPECTOR_ERR_NO_MATRIX_ARGUMENT;
    }
    string name = tokens[1];

    MatrixInfo *matrix = fw->find_matrix_by_list_pos(atoi(name.c_str()));
    //MatrixInfo *matrix = fw->find_matrix(name);
    if (matrix == NULL) {
      return INSPECTOR_ERR_MATRIX_DOES_NOT_EXIST;
    }
    //
    G_using_matrix = matrix;
    describe_matrix(matrix);

    CInspector::prod_dims = new int[matrix->num_dims];
    acc_product_of_dims(matrix, CInspector::prod_dims);
  }

  if (command == "bt") {
    printf("Backtrace:\n");
    fw->print_backtrace(stdout);
    return INSPECTOR_OK;
  }


  if (command == "desc") {
    describe_matrix(G_using_matrix);
    return INSPECTOR_OK;
  }

  if (command == "g" || command == "get") {
    if (G_using_matrix == NULL) {
      return INSPECTOR_ERR_NO_MATRIX_SELECTED_YET;
    }

    // Check number of coordinates
    int num_coords = tokens.size() - 1;
    if (num_coords != G_using_matrix->num_dims) {
      return INSPECTOR_ERR_COORDINATES_ARGUMENT;
    }

    int coords[num_coords];
    for (int i = 0; i < num_coords; i++) {
      int coord = atoi(tokens[i+1].c_str());
      if (coord >= G_using_matrix->N[i]) {
        return INSPECTOR_ERR_OUT_OF_BOUNDS;
      }
      coords[i] = coord;
    }
    //
    int pos = get_pos_by_coordinates(coords, G_using_matrix);

    char coords_buffer[1024];
    list_of_ints(coords_buffer, ", ", coords, num_coords);


    printf("Matrix_%d[%s] == %f (pos %d).\n", G_using_matrix->id, coords_buffer, G_using_matrix->data[pos], pos);
    return INSPECTOR_OK;
  }

  if (command == "s" || command == "set") {
    if (G_using_matrix == NULL) {
      return INSPECTOR_ERR_NO_MATRIX_SELECTED_YET;
    }

    // Check number of coordinates
    int num_coords = tokens.size() - 2;
    if (num_coords != G_using_matrix->num_dims) {
      return INSPECTOR_ERR_COORDINATES_ARGUMENT;
    }

    int coords[num_coords];
    for (int i = 0; i < num_coords; i++) {
      int coord = atoi(tokens[i+1].c_str());
      if (coord >= G_using_matrix->N[i]) {
        return INSPECTOR_ERR_OUT_OF_BOUNDS;
      }
      coords[i] = coord;
    }
    //
    int pos = get_pos_by_coordinates(coords, G_using_matrix);
    float new_value = atof(tokens[num_coords+1].c_str());

    char coords_buffer[1024];
    list_of_ints(coords_buffer, ", ", coords, num_coords);

    printf("Before: M_%d[%s] == %f (pos %d).\n", G_using_matrix->id, coords_buffer, G_using_matrix->data[pos], pos);
    G_using_matrix->data[pos] = new_value;
    printf("After: M_%d[%s] == %f (pos %d).\n", G_using_matrix->id, coords_buffer, G_using_matrix->data[pos], pos);
    return INSPECTOR_OK;
  }

  if (command == "mem") {
    rusage usage;
    int status = getrusage(RUSAGE_SELF, &usage);
    if (status == 0) {
      printf("maximum resident set size: %lu\n", usage.ru_maxrss);
      printf("integral shared memory size: %lu\n", usage.ru_ixrss);
      printf("integral unshared data size: %lu\n", usage.ru_idrss);
      printf("integral unshared stack size: %lu\n", usage.ru_isrss);
      printf("page reclaims (soft page faults): %lu\n", usage.ru_minflt);
      printf("page faults (hard page faults): %lu\n", usage.ru_majflt);
      printf("swaps: %lu\n", usage.ru_nswap);
      printf("block input operations: %lu\n", usage.ru_inblock);
      printf("block output operations: %lu\n", usage.ru_oublock);
      printf("IPC messages sent: %lu\n", usage.ru_msgsnd);
      printf("IPC messages received: %lu\n", usage.ru_msgrcv);
      printf("signals received: %lu\n", usage.ru_nsignals);
      printf("voluntary context switches: %lu\n", usage.ru_nvcsw);
      printf("involuntary context switches: %lu\n", usage.ru_nivcsw);
    }
    return INSPECTOR_OK;
  }

  if (command == "save") {
    if (G_using_matrix == NULL)
      return INSPECTOR_ERR_NO_MATRIX_SELECTED_YET;
    if (tokens.size() != 2)
      return INSPECTOR_ERR_NO_FILENAME;
    //
    char *filename = (char*)tokens[1].c_str();
    int id = G_using_matrix->id;
    fw->save_matrix(G_using_matrix, filename);
    G_using_matrix = fw->find_matrix(id);
    return INSPECTOR_OK;
  }

  if (command == "load") {
    if (G_using_matrix == NULL)
      return INSPECTOR_ERR_NO_MATRIX_SELECTED_YET;
    if (tokens.size() != 2)
      return INSPECTOR_ERR_NO_FILENAME;
    //
    char *filename = (char*)tokens[1].c_str();
    int status = fw->load_matrix(G_using_matrix, filename);
    switch (status) {
      case  0: return INSPECTOR_OK; break;
      case -1: return INSPECTOR_ERR_CAN_NOT_OPEN_FILE; break;
      case -2: return INSPECTOR_ERR_INCOMPATIBLE_DIMENSIONS; break;
      case -3: return INSPECTOR_ERR_READ_ERROR; break;
    }
    return INSPECTOR_OK;
  }


  if (command == "h" || command == "help") {
    printf("Framework CLI inpector. Help not available yet, sorry.\n");
    return INSPECTOR_OK;
  }

  return INSPECTOR_OK;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x4a8, %rsp            # imm = 0x4A8
movq %rsi, %rbx
movq %rdi, %rsi
xorps %xmm0, %xmm0
movaps %xmm0, -0x50(%rbp)
andq $0x0, -0x40(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x33a0
leaq -0x50(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x5a0c
movl %eax, %r14d
leaq -0xa8(%rbp), %rdi
callq 0x3170
testl %r14d, %r14d
je 0x5d23
movq -0x50(%rbp), %rsi
leaq -0x70(%rbp), %rdi
callq 0x33a0
leaq -0xc8(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x33a0
leaq -0xc8(%rbp), %r15
movq %r15, %rdi
movl %r14d, %esi
callq 0x5bc2
movl %eax, %r14d
movq %r15, %rdi
callq 0x3170
testb %r14b, %r14b
je 0x5d27
leaq 0x2998(%rip), %rsi      # 0x868e
leaq -0x70(%rbp), %rdi
callq 0x665a
testb %al, %al
jne 0x5d17
leaq 0x297b(%rip), %rsi      # 0x8685
leaq -0x70(%rbp), %rdi
callq 0x665a
testb %al, %al
je 0x5d4d
movq %rbx, %rdi
callq 0x379c
xorl %ebx, %ebx
jmp 0x5d2a
xorl %ebx, %ebx
jmp 0x5d33
pushq $-0x1
popq %rbx
leaq -0x70(%rbp), %rdi
callq 0x3170
leaq -0x50(%rbp), %rdi
callq 0x6668
movl %ebx, %eax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x293c(%rip), %rsi      # 0x8690
leaq -0x70(%rbp), %rdi
callq 0x665a
testb %al, %al
jne 0x5d79
leaq 0x2922(%rip), %rsi      # 0x868a
leaq -0x70(%rbp), %rdi
callq 0x665a
testb %al, %al
je 0x5e08
movq -0x50(%rbp), %rsi
movq -0x48(%rbp), %rax
subq %rsi, %rax
cmpq $0x40, %rax
jne 0x5e3f
addq $0x20, %rsi
leaq -0x4d0(%rbp), %rdi
callq 0x33a0
movq -0x4d0(%rbp), %rdi
callq 0x3440
movq %rbx, %rdi
movl %eax, %esi
callq 0x3a9c
movq %rax, %r14
testq %rax, %rax
je 0x5e6b
movq %r14, 0x6521(%rip)      # 0xc2e8
movq %r14, %rdi
callq 0x5b64
movslq 0xc(%r14), %rax
leaq (,%rax,4), %rcx
testq %rax, %rax
pushq $-0x1
popq %rdi
cmovnsq %rcx, %rdi
callq 0x3030
movq %rax, 0x64ff(%rip)      # 0xc2f0
movq %r14, %rdi
movq %rax, %rsi
callq 0x5c08
leaq -0x4d0(%rbp), %rdi
callq 0x3170
leaq 0x2883(%rip), %rsi      # 0x8692
leaq -0x70(%rbp), %rdi
callq 0x665a
testb %al, %al
je 0x5e46
leaq 0x2cb2(%rip), %rdi      # 0x8ad5
callq 0x3430
movq 0x6159(%rip), %rax      # 0xbf88
movq (%rax), %rsi
movq %rbx, %rdi
callq 0x3ca4
jmp 0x5d1f
pushq $-0x2
jmp 0x5d29
leaq 0x2848(%rip), %rsi      # 0x8695
leaq -0x70(%rbp), %rdi
callq 0x665a
testb %al, %al
je 0x5e7e
movq 0x6487(%rip), %rdi      # 0xc2e8
callq 0x5b64
jmp 0x5d1f
leaq -0x4d0(%rbp), %rdi
callq 0x3170
pushq $-0x3
jmp 0x5d29
leaq 0x2815(%rip), %rsi      # 0x869a
leaq -0x70(%rbp), %rdi
callq 0x665a
testb %al, %al
jne 0x5eaa
leaq 0x2803(%rip), %rsi      # 0x869c
leaq -0x70(%rbp), %rdi
callq 0x665a
testb %al, %al
je 0x5f45
movq 0x6437(%rip), %rax      # 0xc2e8
testq %rax, %rax
je 0x6348
movq -0x48(%rbp), %rcx
subq -0x50(%rbp), %rcx
shrq $0x5, %rcx
decl %ecx
cmpl 0xc(%rax), %ecx
jne 0x6013
movq %rsp, -0x80(%rbp)
movl %ecx, %eax
movq %rsp, %rdx
leaq 0xf(,%rax,4), %rax
andq $-0x10, %rax
subq %rax, %rdx
movq %rdx, -0x30(%rbp)
movq %rdx, %rsp
movq -0x50(%rbp), %r13
movq 0x63ed(%rip), %r12      # 0xc2e8
xorl %r14d, %r14d
testl %ecx, %ecx
movl $0x0, %r15d
movq %rcx, -0x78(%rbp)
cmovgl %ecx, %r15d
shlq $0x2, %r15
pushq $-0x6
popq %rbx
cmpq %r14, %r15
je 0x601a
movq 0x20(%r13,%r14,8), %rdi
callq 0x3440
movq 0x10(%r12), %rcx
cmpl (%rcx,%r14), %eax
jge 0x6071
movq -0x30(%rbp), %rcx
movl %eax, (%rcx,%r14)
addq $0x4, %r14
jmp 0x5f15
leaq 0x2274(%rip), %rsi      # 0x81c0
leaq -0x70(%rbp), %rdi
callq 0x665a
testb %al, %al
jne 0x5f71
leaq 0x2762(%rip), %rsi      # 0x86c2
leaq -0x70(%rbp), %rdi
callq 0x665a
testb %al, %al
je 0x607a
movq 0x6370(%rip), %rax      # 0xc2e8
testq %rax, %rax
je 0x6348
movq -0x48(%rbp), %rdx
subq -0x50(%rbp), %rdx
movq %rdx, %rcx
shrq $0x5, %rcx
addl $-0x2, %ecx
cmpl 0xc(%rax), %ecx
jne 0x6013
movq %rdx, -0x88(%rbp)
movq %rsp, -0x80(%rbp)
movl %ecx, %eax
movq %rsp, %rdx
leaq 0xf(,%rax,4), %rax
andq $-0x10, %rax
subq %rax, %rdx
movq %rdx, %r13
movq %rdx, %rsp
movq -0x50(%rbp), %rax
movq %rax, -0x30(%rbp)
movq 0x631c(%rip), %r12      # 0xc2e8
xorl %r14d, %r14d
testl %ecx, %ecx
movl $0x0, %r15d
movq %rcx, -0x78(%rbp)
cmovgl %ecx, %r15d
shlq $0x2, %r15
pushq $-0x6
popq %rbx
cmpq %r14, %r15
je 0x6239
movq -0x30(%rbp), %rax
movq 0x20(%rax,%r14,8), %rdi
callq 0x3440
movq 0x10(%r12), %rcx
cmpl (%rcx,%r14), %eax
jge 0x6071
movl %eax, (%r13,%r14)
addq $0x4, %r14
jmp 0x5fe6
pushq $-0x5
jmp 0x5d29
movq -0x30(%rbp), %r14
movq %r14, %rdi
movq %r12, %rsi
callq 0x5c30
movl %eax, %ebx
leaq 0x266e(%rip), %rsi      # 0x86a0
leaq -0x4d0(%rbp), %r12
movq %r12, %rdi
movq %r14, %rdx
movq -0x78(%rbp), %rcx
callq 0x5ae2
movq 0x6299(%rip), %rax      # 0xc2e8
movl 0x8(%rax), %esi
movq 0x18(%rax), %rax
movslq %ebx, %rcx
cvtss2sd (%rax,%rcx,4), %xmm0
leaq 0x263e(%rip), %rdi      # 0x86a3
movq %r12, %rdx
movb $0x1, %al
callq 0x3070
xorl %ebx, %ebx
movq -0x80(%rbp), %rsp
jmp 0x5d2a
leaq 0x2688(%rip), %rsi      # 0x8709
leaq -0x70(%rbp), %rdi
callq 0x665a
testb %al, %al
je 0x61d5
xorl %ebx, %ebx
leaq -0x4d0(%rbp), %rsi
xorl %edi, %edi
callq 0x31a0
testl %eax, %eax
jne 0x5d2a
movq -0x4b0(%rbp), %rsi
leaq 0x2655(%rip), %rdi      # 0x870d
xorl %eax, %eax
callq 0x3070
movq -0x4a8(%rbp), %rsi
leaq 0x2660(%rip), %rdi      # 0x872d
xorl %eax, %eax
callq 0x3070
movq -0x4a0(%rbp), %rsi
leaq 0x266d(%rip), %rdi      # 0x874f
xorl %eax, %eax
callq 0x3070
movq -0x498(%rbp), %rsi
leaq 0x267a(%rip), %rdi      # 0x8771
xorl %eax, %eax
callq 0x3070
movq -0x490(%rbp), %rsi
leaq 0x2688(%rip), %rdi      # 0x8794
xorl %eax, %eax
callq 0x3070
movq -0x488(%rbp), %rsi
leaq 0x269a(%rip), %rdi      # 0x87bb
xorl %eax, %eax
callq 0x3070
movq -0x480(%rbp), %rsi
leaq 0x26aa(%rip), %rdi      # 0x87e0
xorl %eax, %eax
callq 0x3070
movq -0x478(%rbp), %rsi
leaq 0x26a1(%rip), %rdi      # 0x87ec
xorl %eax, %eax
callq 0x3070
movq -0x470(%rbp), %rsi
leaq 0x26a9(%rip), %rdi      # 0x8809
xorl %eax, %eax
callq 0x3070
movq -0x468(%rbp), %rsi
leaq 0x26b2(%rip), %rdi      # 0x8827
xorl %eax, %eax
callq 0x3070
movq -0x460(%rbp), %rsi
leaq 0x26b5(%rip), %rdi      # 0x883f
xorl %eax, %eax
callq 0x3070
movq -0x458(%rbp), %rsi
leaq 0x26bc(%rip), %rdi      # 0x885b
xorl %eax, %eax
callq 0x3070
movq -0x450(%rbp), %rsi
leaq 0x26c0(%rip), %rdi      # 0x8874
xorl %eax, %eax
callq 0x3070
movq -0x448(%rbp), %rsi
leaq 0x26a9(%rip), %rdi      # 0x8872
xorl %eax, %eax
callq 0x3070
jmp 0x5d2a
leaq 0x26b9(%rip), %rsi      # 0x8895
leaq -0x70(%rbp), %rdi
callq 0x665a
testb %al, %al
je 0x62f0
movq 0x60f4(%rip), %rsi      # 0xc2e8
testq %rsi, %rsi
je 0x6348
movq -0x50(%rbp), %rax
movq -0x48(%rbp), %rcx
subq %rax, %rcx
cmpq $0x40, %rcx
jne 0x638c
movq 0x20(%rax), %rdx
movl 0x8(%rsi), %r14d
movq %rbx, %rdi
callq 0x3ad2
movq %rbx, %rdi
movl %r14d, %esi
callq 0x3a20
movq %rax, 0x60b4(%rip)      # 0xc2e8
jmp 0x5d1f
movq %r13, %rdi
movq %r12, %rsi
callq 0x5c30
movl %eax, %r12d
movq -0x88(%rbp), %rcx
shlq $0x1b, %rcx
movabsq $-0x100000000, %rax     # imm = 0xFFFFFFFF00000000
addq %rcx, %rax
sarq $0x1b, %rax
movq -0x30(%rbp), %rcx
movq (%rcx,%rax), %rdi
callq 0x3360
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x30(%rbp)
leaq 0x2420(%rip), %rsi      # 0x86a0
leaq -0x4d0(%rbp), %rbx
movq %rbx, %rdi
movq %r13, %rdx
movq -0x78(%rbp), %rcx
callq 0x5ae2
movq 0x604b(%rip), %rax      # 0xc2e8
movl 0x8(%rax), %esi
movq 0x18(%rax), %rax
movslq %r12d, %r14
cvtss2sd (%rax,%r14,4), %xmm0
leaq 0x2412(%rip), %rdi      # 0x86c6
movq %rbx, %rdx
movl %r14d, %ecx
movb $0x1, %al
callq 0x3070
movq 0x6020(%rip), %rax      # 0xc2e8
movq 0x18(%rax), %rcx
movss -0x30(%rbp), %xmm0
movss %xmm0, (%rcx,%r14,4)
movl 0x8(%rax), %esi
cvtss2sd %xmm0, %xmm0
leaq 0x2403(%rip), %rdi      # 0x86e8
movq %rbx, %rdx
movl %r14d, %ecx
jmp 0x6068
leaq 0x25a3(%rip), %rsi      # 0x889a
leaq -0x70(%rbp), %rdi
callq 0x665a
testb %al, %al
je 0x634f
movq 0x5fdd(%rip), %rsi      # 0xc2e8
testq %rsi, %rsi
je 0x6348
movq -0x50(%rbp), %rax
movq -0x48(%rbp), %rcx
subq %rax, %rcx
cmpq $0x40, %rcx
jne 0x638c
movq 0x20(%rax), %rdx
movq %rbx, %rdi
callq 0x3ba8
cmpl $-0x4, %eax
jbe 0x5d1f
cltq
leaq 0x27b9(%rip), %rcx      # 0x8af8
movl 0xc(%rcx,%rax,4), %ebx
jmp 0x5d2a
pushq $-0x4
jmp 0x5d29
leaq 0x2549(%rip), %rsi      # 0x889f
leaq -0x70(%rbp), %rdi
callq 0x665a
testb %al, %al
jne 0x637b
leaq 0x2537(%rip), %rsi      # 0x88a1
leaq -0x70(%rbp), %rdi
callq 0x665a
testb %al, %al
je 0x5d1f
leaq 0x271c(%rip), %rdi      # 0x8a9e
callq 0x3430
jmp 0x5d1f
pushq $-0x7
jmp 0x5d29
jmp 0x63ac
jmp 0x63ac
jmp 0x63ac
movq %rax, %rbx
leaq -0x4d0(%rbp), %rdi
callq 0x3170
jmp 0x63af
jmp 0x63c6
movq %rax, %rbx
leaq -0x70(%rbp), %rdi
jmp 0x63bf
movq %rax, %rbx
leaq -0xa8(%rbp), %rdi
callq 0x3170
jmp 0x63c9
movq %rax, %rbx
leaq -0x50(%rbp), %rdi
callq 0x6668
movq %rbx, %rdi
callq 0x34c0