// File: ChristalC[P]Online-Outlier-Detection/lof.cpp
// Function: Lof::addPoint(std::vector<double, std::allocator<double>>)
bool Lof::addPoint(vector<double> new_pos) {
  Point* new_point = new Point(new_pos);
  all_points.push_back(new_point);
  point_count++;
  // If lof_data.dimension is not fixed (== 0), set it to dimension of new_point.
  if (dimension == 0) {
    dimension = new_point->getDimension();
  }
  // If lof_data.dimension is fixed, compare with new_point dimension to confirm consistency
  else if (dimension != new_point->getDimension()) {
    cout << "New point dimension is inconsistent. End the program!" << endl;
    return false;
  }
  auto it = all_points.begin();
  for (; it != prev(all_points.end()); it++) {
    (*it)->addNewNeighbor(new_point);
    new_point->insertNeighbor(*it);
  }
  bool is_outlier = false;
  // If group_size is set (!= 0), update stats of the new point
  // If group_size is fixed, which means decision is needed on if the new_point is an outlier
  if (group_size != 0) {
    new_point->updateStats();
    double lof_val = new_point->getLofVal();
    if (lof_val > threshold) {
      cout << "Found an outlier: ";
      new_point->displayPoint();
    }
    removeFrontPoint();
  }
  // If the group_size is not fixed, count if the new_point is outside the first window
  // If it is, then we need to decide group_size and threshold at this point
  // If not, no action or decision needed
  else {  
    if (getPointCount() == window_size + 1) {
      int best_group_size = decideGroupSize();
      changeGroupSize(best_group_size);

      double th = decideThreshold();
      setThreshold(th);

      // Decide if the newly added point is an outlier based on group_size and threshold
      double lof_val = new_point->getLofVal();
      if (lof_val > threshold) {
        cout << "Found an outlier: ";
        new_point->displayPoint();
      }
      removeFrontPoint();
    }
  }
  return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rsi, -0xa0(%rbp)
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xa8(%rbp)
movl $0x70, %edi
callq 0x3290
movq -0xa0(%rbp), %rsi
movq %rax, -0x98(%rbp)
movb $0x1, -0x45(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x6820
jmp 0x5fac
movq -0x98(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x3730
jmp 0x5fbe
movb $0x0, -0x45(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x3fa0
movq -0x98(%rbp), %rax
movq -0xa8(%rbp), %rdi
movq %rax, -0x20(%rbp)
addq $0x18, %rdi
leaq -0x20(%rbp), %rsi
callq 0x6910
movq -0xa8(%rbp), %rax
movl 0xc(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0xc(%rax)
cmpl $0x0, (%rax)
jne 0x6059
movq -0x20(%rbp), %rdi
callq 0x6950
movl %eax, %ecx
movq -0xa8(%rbp), %rax
movl %ecx, (%rax)
jmp 0x60aa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x603b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x3fa0
testb $0x1, -0x45(%rbp)
jne 0x6043
jmp 0x6054
movq -0x98(%rbp), %rdi
movl $0x70, %esi
callq 0x32a0
jmp 0x6275
movq -0xa8(%rbp), %rax
movl (%rax), %eax
movl %eax, -0xac(%rbp)
movq -0x20(%rbp), %rdi
callq 0x6950
movl %eax, %ecx
movl -0xac(%rbp), %eax
cmpl %ecx, %eax
je 0x60a8
movq 0xdf44(%rip), %rdi      # 0x13fc8
leaq 0x6f8d(%rip), %rsi      # 0xd018
callq 0x3280
movq %rax, %rdi
movq 0xdf16(%rip), %rsi      # 0x13fb0
callq 0x32d0
movb $0x0, -0x1(%rbp)
jmp 0x6267
jmp 0x60aa
movq -0xa8(%rbp), %rdi
addq $0x18, %rdi
callq 0x66f0
movq %rax, -0x50(%rbp)
movq -0xa8(%rbp), %rdi
addq $0x18, %rdi
callq 0x6750
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rdi
movl $0x1, %esi
callq 0x6970
movq %rax, -0x58(%rbp)
leaq -0x50(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x6720
testb $0x1, %al
jne 0x60f7
jmp 0x6143
leaq -0x50(%rbp), %rdi
callq 0x6780
movq (%rax), %rdi
movq -0x20(%rbp), %rsi
callq 0x38e0
movq -0x20(%rbp), %rax
movq %rax, -0xb8(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x6780
movq -0xb8(%rbp), %rdi
movq (%rax), %rsi
callq 0x37e0
leaq -0x50(%rbp), %rdi
xorl %esi, %esi
callq 0x67d0
movq %rax, -0x68(%rbp)
jmp 0x60be
movq -0xa8(%rbp), %rax
movb $0x0, -0x69(%rbp)
cmpl $0x0, 0x8(%rax)
je 0x61ab
movq -0x20(%rbp), %rdi
callq 0x3970
movq -0x20(%rbp), %rdi
callq 0x69b0
movq -0xa8(%rbp), %rax
movsd %xmm0, -0x78(%rbp)
movsd -0x78(%rbp), %xmm0
ucomisd 0x10(%rax), %xmm0
jbe 0x619a
movq 0xde43(%rip), %rdi      # 0x13fc8
leaq 0x6ec2(%rip), %rsi      # 0xd04e
callq 0x3280
movq -0x20(%rbp), %rdi
callq 0x3c50
movq -0xa8(%rbp), %rdi
callq 0x6280
jmp 0x6263
movq -0xa8(%rbp), %rdi
callq 0x69d0
movq -0xa8(%rbp), %rcx
movl 0x4(%rcx), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
jne 0x6261
movq -0xa8(%rbp), %rdi
callq 0x6360
movq -0xa8(%rbp), %rdi
movl %eax, -0x7c(%rbp)
movl -0x7c(%rbp), %esi
callq 0x6410
movq -0xa8(%rbp), %rdi
callq 0x6570
movq -0xa8(%rbp), %rdi
movsd %xmm0, -0x88(%rbp)
movsd -0x88(%rbp), %xmm0
callq 0x69f0
movq -0x20(%rbp), %rdi
callq 0x69b0
movq -0xa8(%rbp), %rax
movsd %xmm0, -0x90(%rbp)
movsd -0x90(%rbp), %xmm0
ucomisd 0x10(%rax), %xmm0
jbe 0x6255
movq 0xdd88(%rip), %rdi      # 0x13fc8
leaq 0x6e07(%rip), %rsi      # 0xd04e
callq 0x3280
movq -0x20(%rbp), %rdi
callq 0x3c50
movq -0xa8(%rbp), %rdi
callq 0x6280
jmp 0x6263
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0xc0, %rsp
popq %rbp
retq
movq -0x40(%rbp), %rdi
callq 0x3450
nop