#import "LPStackTraceGenerator.h"

#include <execinfo.h>
#include <mach/mach.h>

#if defined(__x86_64__) || defined(__arm64__)

// To get the FP_LINK_OFFSET and ISALIGNED for the new architecture,
// please check the lastest version of
// https://opensource.apple.com/source/Libc/Libc-1272.250.1/gen/thread_stack_pcs.c.auto.html
#if defined(__x86_64__) || defined(__arm64__)
#define FP_LINK_OFFSET 1
#endif

#if defined(__x86_64__)
#define ISALIGNED(a) ((((uintptr_t)(a)) & 0xf) == 0)
#elif defined(__arm64__)
#define ISALIGNED(a) ((((uintptr_t)(a)) & 0x1) == 0)
#endif

#define ISVALID(a) \
  ((a) >= stackbot && (a) <= stacktop && frame != NULL && (uintptr_t)a >= 4096 && ISALIGNED(a))

static _STRUCT_MCONTEXT GetContext(pthread_t pthread);
static void *GetFP(_STRUCT_MCONTEXT ctx);
static void *GetPC(_STRUCT_MCONTEXT ctx);
static bool SafeReadMemory(vm_address_t src, void *dest, size_t len);
/**
 * Stack unwind by using frame pointer.
 *
 * @param buffer Output. Array of addresses.
 * @param max Size of buffer.
 * @param *frames Output. Number of acutal frames.
 * @param thread Target Thread.
 * @param frame Frame pointer of target thread.
 */
static void TheadStackUnwind(vm_address_t *buffer, unsigned max, unsigned *frames, pthread_t thread,
                             void *frame);
static NSString *getThreadName(pthread_t thread);

static inline _STRUCT_MCONTEXT GetContext(pthread_t pthread) {
  thread_t thread = pthread_mach_thread_np(pthread);
  _STRUCT_MCONTEXT ctx;
#if defined(__x86_64__)
  mach_msg_type_number_t count = x86_THREAD_STATE64_COUNT;
  thread_get_state(thread, x86_THREAD_STATE64, (thread_state_t)&ctx.__ss, &count);
#elif defined(__arm64__)
  mach_msg_type_number_t count = ARM_THREAD_STATE64_COUNT;
  thread_get_state(thread, ARM_THREAD_STATE64, (thread_state_t)&ctx.__ss, &count);
#endif

  return ctx;
}

static inline void *GetFP(_STRUCT_MCONTEXT ctx) {
#if defined(__x86_64__)
  void *fp = (void *)ctx.__ss.__rbp;
#elif defined(__arm64__)
  void *fp = (void *)ctx.__ss.__fp;
#endif
  return fp;
}

static inline void *GetPC(_STRUCT_MCONTEXT ctx) {
#if defined(__x86_64__)
  void *pc = (void *)ctx.__ss.__rip;
#elif defined(__arm64__)
  void *pc = (void *)ctx.__ss.__pc;
#endif
  return pc;
}

static bool SafeReadMemory(vm_address_t src, void *dest, size_t len) {
  vm_size_t readSize = len;
  return vm_read_overwrite(mach_task_self(), src, len, (pointer_t)dest, &readSize) == KERN_SUCCESS;
}

static void TheadStackUnwind(vm_address_t *buffer, unsigned max, unsigned *frames, pthread_t thread,
                             void *frame) {
  void *next;
  void *stacktop = pthread_get_stackaddr_np(thread);
  void *stackbot = stacktop - pthread_get_stacksize_np(thread);

  *frames = 0;

  // make sure return address is never out of bounds
  stacktop -= (FP_LINK_OFFSET + 1) * sizeof(void *);

  if (!ISVALID(frame)) return;

  while (max--) {
    buffer[*frames] = *(vm_address_t *)(((void **)frame) + FP_LINK_OFFSET);
    (*frames)++;
    if (!SafeReadMemory((vm_address_t)frame, &next, sizeof(next))) {
      NSLog(@"Unable to read memory in stack unwinding. Address: %llu", (uint64_t)frame);
      return;
    }
    if (!ISVALID(next) || next <= frame) return;
    frame = next;
  }
}

static NSString *getThreadName(pthread_t thread) {
  char name[128];
  if (pthread_getname_np(thread, name, sizeof(name)) != 0) {
    return @"";
  }
  return [NSString stringWithCString:name encoding:NSASCIIStringEncoding];
}

int LPSnapshotThreadStackTrace(void **buffer, int size, pthread_t thread) {
  if (buffer == NULL || size == 0) {
    return 0;
  }

  unsigned int num_frames;
  _STRUCT_MCONTEXT ctx = GetContext(thread);
  // Current instruction.
  void *frame = GetFP(ctx);
  buffer[0] = GetPC(ctx);

  TheadStackUnwind((vm_address_t *)buffer + 1, --size, &num_frames, thread, frame);

  // Index 0 is used by the current instruction.
  num_frames += 1;

  while (num_frames >= 1 && buffer[num_frames - 1] == NULL) {
    num_frames -= 1;
  }
  return num_frames;
}

int LPSnapshotAllThreadsStackTrace(LPThreadStackTrace *buffer, int size) {
  if (buffer == NULL || size == 0) {
    return 0;
  }

  mach_msg_type_number_t threads_count;
  thread_act_array_t threads_list;
  task_threads(mach_task_self(), &threads_list, &threads_count);
  int count;

  for (count = 0; count < threads_count && count < size; ++count) {
    pthread_t pthread = pthread_from_mach_thread_np(threads_list[count]);
    int frames = LPSnapshotThreadStackTrace(buffer[count].stacktrace,
                                            kLPThreadStackTraceMaxFramesCount, pthread);
    buffer[count].frames = frames;
    buffer[count].thread = pthread;
  }

  return count;
}

NSArray<NSString *> *LPStackTraceString(void **buffer, int size) {
  if (buffer == NULL || size == 0) {
    return @[];
  }

  char **strings = backtrace_symbols(buffer, size);

  if (strings == NULL) {
    return @[];
  }

  NSMutableArray<NSString *> *result = [NSMutableArray array];
  for (int i = 0; i < size; i++) {
    [result addObject:[NSString stringWithCString:strings[i] encoding:NSASCIIStringEncoding]];
  }
  free(strings);
  return result;
}

NSArray<NSArray<NSString *> *> *LPStackTracesString(LPThreadStackTrace *buffer, int size) {
  if (buffer == NULL || size == 0) {
    return @[];
  }

  NSMutableArray<NSArray<NSString *> *> *result = [NSMutableArray array];
  for (int i = 0; i < size; i++) {
    NSMutableArray<NSString *> *threadResult = [NSMutableArray array];
    [threadResult addObject:[NSString stringWithFormat:@"Thread %d name: %@", i,
                                                       getThreadName(buffer[i].thread)]];
    [threadResult addObjectsFromArray:LPStackTraceString(buffer[i].stacktrace, buffer[i].frames)];

    [result addObject:threadResult];
  }

  return result;
}
#endif
