// This test is intended to create a situation in which multiple events
// (breakpoints, watchpoints, crashes, and signal generation/delivery) happen
// from multiple threads. The test expects the debugger to set a breakpoint on
// the main thread (before any worker threads are spawned) and modify variables
// which control the number of threads that are spawned for each action.

#include "pseudo_barrier.h"
#include <vector>

#include <pthread.h>

#include <signal.h>
#include <sys/types.h>
#include <unistd.h>

typedef std::vector<std::pair<unsigned, void*(*)(void*)> > action_counts;
typedef std::vector<pthread_t> thread_vector;

pseudo_barrier_t g_barrier;
int g_breakpoint = 0;
int g_sigusr1_count = 0;

// Hardware watchpoints round the watched address/size to an alignment
// boundary, so a watchpoint on a plain global could end up covering a
// neighboring global too. Group the watched data with trailing padding in a
// single aligned struct so the compiler is guaranteed to lay them out
// together and nothing else can share the watchpoint's range.
#define WATCHPOINT_SIZE 16
struct alignas(WATCHPOINT_SIZE) WatchMePadding {
  uint32_t data;
  char padding_after[WATCHPOINT_SIZE];
} g_watchme;

struct action_args {
  int delay;
};

// Perform any extra actions required by thread 'input' arg
void do_action_args(void *input) {
    if (input) {
      action_args *args = static_cast<action_args*>(input);
      sleep(args->delay);
    }
}

void *
breakpoint_func (void *input)
{
    // Wait until all threads are running
    pseudo_barrier_wait(g_barrier);
    do_action_args(input);

    // Do something
    g_breakpoint++;       // Set breakpoint here
    return 0;
}

void *
signal_func (void *input) {
    // Wait until all threads are running
    pseudo_barrier_wait(g_barrier);
    do_action_args(input);

    // Send a user-defined signal to the current process
    //kill(getpid(), SIGUSR1);
    // Send a user-defined signal to the current thread
    pthread_kill(pthread_self(), SIGUSR1);

    return 0;
}

void *
watchpoint_func (void *input) {
    pseudo_barrier_wait(g_barrier);
    do_action_args(input);

    g_watchme.data = 1; // watchpoint triggers here
    return 0;
}

void *
crash_func (void *input) {
    pseudo_barrier_wait(g_barrier);
    do_action_args(input);

    int *a = 0;
    *a = 5; // crash happens here
    return 0;
}

void sigusr1_handler(int sig) {
    if (sig == SIGUSR1)
        g_sigusr1_count += 1; // Break here in signal handler
}

/// Register a simple function for to handle signal
void register_signal_handler(int signal, void (*handler)(int))
{
    sigset_t empty_sigset;
    sigemptyset(&empty_sigset);

    struct sigaction action;
    action.sa_sigaction = 0;
    action.sa_mask = empty_sigset;
    action.sa_flags = 0;
    action.sa_handler = handler;
    sigaction(SIGUSR1, &action, 0);
}

void start_threads(thread_vector& threads,
                   action_counts& actions,
                   void* args = 0) {
    action_counts::iterator b = actions.begin(), e = actions.end();
    for(action_counts::iterator i = b; i != e; ++i) {
        for(unsigned count = 0; count < i->first; ++count) {
            pthread_t t;
            pthread_create(&t, 0, i->second, args);
            threads.push_back(t);
        }
    }
}

int dotest()
{
  g_watchme.data = 0;

  // Actions are triggered immediately after the thread is spawned
  unsigned num_breakpoint_threads = 1;
  unsigned num_watchpoint_threads = 0;
  unsigned num_signal_threads = 1;
  unsigned num_crash_threads = 0;

  // Actions below are triggered after a 1-second delay
  unsigned num_delay_breakpoint_threads = 0;
  unsigned num_delay_watchpoint_threads = 0;
  unsigned num_delay_signal_threads = 0;
  unsigned num_delay_crash_threads = 0;

  // clang-format off
  register_signal_handler(SIGUSR1, sigusr1_handler); // Break here and adjust num_[breakpoint|watchpoint|signal|crash]_threads
  // clang-format on

  unsigned total_threads = num_breakpoint_threads + num_watchpoint_threads +
                           num_signal_threads + num_crash_threads +
                           num_delay_breakpoint_threads +
                           num_delay_watchpoint_threads +
                           num_delay_signal_threads + num_delay_crash_threads;

  // Don't let either thread do anything until they're both ready.
  pseudo_barrier_init(g_barrier, total_threads);

  action_counts actions;
  actions.push_back(std::make_pair(num_breakpoint_threads, breakpoint_func));
  actions.push_back(std::make_pair(num_watchpoint_threads, watchpoint_func));
  actions.push_back(std::make_pair(num_signal_threads, signal_func));
  actions.push_back(std::make_pair(num_crash_threads, crash_func));

  action_counts delay_actions;
  delay_actions.push_back(
      std::make_pair(num_delay_breakpoint_threads, breakpoint_func));
  delay_actions.push_back(
      std::make_pair(num_delay_watchpoint_threads, watchpoint_func));
  delay_actions.push_back(
      std::make_pair(num_delay_signal_threads, signal_func));
  delay_actions.push_back(std::make_pair(num_delay_crash_threads, crash_func));

  // Create threads that handle instant actions
  thread_vector threads;
  start_threads(threads, actions);

  // Create threads that handle delayed actions
  action_args delay_arg;
  delay_arg.delay = 1;
  start_threads(threads, delay_actions, &delay_arg);

  // Join all threads
  typedef std::vector<pthread_t>::iterator thread_iterator;
  for (thread_iterator t = threads.begin(); t != threads.end(); ++t)
    pthread_join(*t, 0);

  return 0;
}

int main ()
{
    dotest();
    return 0; // Break here and verify one thread is active.
}


