// TODO: Investigate these failures
// XFAIL: asan, tsan, ubsan

// TODO: Investigate these failures on x86_64 macOS back deployment
// UNSUPPORTED: target=x86_64-apple-darwin{{.+}}

#include <libunwind.h>
#include <stdlib.h>
#include <string.h>

void backtrace(int lower_bound) {
  unw_context_t context;
  unw_getcontext(&context);

  unw_cursor_t cursor;
  unw_init_local(&cursor, &context);

  int n = 0;
  do {
    ++n;
    if (n > 100) {
      abort();
    }
  } while (unw_step(&cursor) > 0);

  if (n < lower_bound) {
    abort();
  }
}

void test1(int i) {
  backtrace(i);
}

void test2(int i, int j) {
  backtrace(i);
  test1(j);
}

void test3(int i, int j, int k) {
  backtrace(i);
  test2(j, k);
}

void test_no_info() {
  unw_context_t context;
  unw_getcontext(&context);

  unw_cursor_t cursor;
  unw_init_local(&cursor, &context);

  unw_proc_info_t info;
  int ret = unw_get_proc_info(&cursor, &info);
  if (ret != UNW_ESUCCESS)
    abort();

  // Set the IP to an address clearly outside any function.
  unw_set_reg(&cursor, UNW_REG_IP, (unw_word_t)0);

  ret = unw_get_proc_info(&cursor, &info);
  if (ret != UNW_ENOINFO)
    abort();
}

void test_reg_names() {
  unw_context_t context;
  unw_getcontext(&context);

  unw_cursor_t cursor;
  unw_init_local(&cursor, &context);

  int max_reg_num = -100;
#if defined(__i386__)
  max_reg_num = 7;
#elif defined(__x86_64__)
  max_reg_num = 32;
#endif

  const char prefix[] = "unknown";
  for (int i = -2; i < max_reg_num; ++i) {
    if (strncmp(prefix, unw_regname(&cursor, i), sizeof(prefix) - 1) == 0)
      abort();
  }

  if (strncmp(prefix, unw_regname(&cursor, max_reg_num + 1),
              sizeof(prefix) - 1) != 0)
    abort();
}

#if defined(__x86_64__)
void test_reg_get_set() {
  unw_context_t context;
  unw_getcontext(&context);

  unw_cursor_t cursor;
  unw_init_local(&cursor, &context);

  for (int i = 0; i < 17; ++i) {
    const unw_word_t set_value = 7;
    if (unw_set_reg(&cursor, i, set_value) != UNW_ESUCCESS)
      abort();

    unw_word_t get_value = 0;
    if (unw_get_reg(&cursor, i, &get_value) != UNW_ESUCCESS)
      abort();

    if (set_value != get_value)
      abort();
  }
}

void test_fpreg_get_set() {
  unw_context_t context;
  unw_getcontext(&context);

  unw_cursor_t cursor;
  unw_init_local(&cursor, &context);

  // get/set is not implemented for x86_64 fpregs.
  for (int i = 17; i < 33; ++i) {
    const unw_fpreg_t set_value = 7;
    if (unw_set_fpreg(&cursor, i, set_value) != UNW_EBADREG)
      abort();

    unw_fpreg_t get_value = 0;
    if (unw_get_fpreg(&cursor, i, &get_value) != UNW_EBADREG)
      abort();
  }
}
#else
void test_reg_get_set() {}
void test_fpreg_get_set() {}
#endif

int main(int, char**) {
  test1(1);
  test2(1, 2);
  test3(1, 2, 3);
  test_no_info();
  test_reg_names();
  test_reg_get_set();
  test_fpreg_get_set();
  return 0;
}
