/*
 * Check: a unit test framework for C
 * Copyright (C) 2001, 2002 Arien Malec
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 */

#include "libcompat/libcompat.h"

#include <sys/types.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <signal.h>
#include <setjmp.h>

#include "internal-check.h"
#include "check_error.h"
#include "check_list.h"
#include "check_impl.h"
#include "check_msg.h"
#include "check_log.h"

enum rinfo
{
  CK_R_SIG,
  CK_R_PASS,
  CK_R_EXIT,
  CK_R_FAIL_TEST,
  CK_R_FAIL_FIXTURE
};

enum tf_type
{
  CK_FORK_TEST,
  CK_NOFORK_TEST,
  CK_NOFORK_FIXTURE
};


/* all functions are defined in the same order they are declared.
   functions that depend on forking are gathered all together.
   non-static functions are at the end of the file. */
static void srunner_run_init (SRunner * sr, enum print_output print_mode);
static void srunner_run_end (SRunner * sr, enum print_output print_mode);
static void srunner_iterate_suites (SRunner * sr,
    const char *sname, const char *tcname,
    const char *include_tags,
    const char *exclude_tags, enum print_output print_mode);
static void srunner_iterate_tcase_tfuns (SRunner * sr, TCase * tc);
static void srunner_add_failure (SRunner * sr, TestResult * tf);
static TestResult *srunner_run_setup (List * func_list,
    enum fork_status fork_usage, const char *test_name, const char *setup_name);
static int srunner_run_unchecked_setup (SRunner * sr, TCase * tc);
static TestResult *tcase_run_checked_setup (SRunner * sr, TCase * tc);
static void srunner_run_teardown (List * fixture_list,
    enum fork_status fork_usage);
static void srunner_run_unchecked_teardown (SRunner * sr, TCase * tc);
static void tcase_run_checked_teardown (TCase * tc);
static void srunner_run_tcase (SRunner * sr, TCase * tc);
static TestResult *tcase_run_tfun_nofork (SRunner * sr, TCase * tc, TF * tf,
    int i);
static TestResult *receive_result_info_nofork (const char *tcname,
    const char *tname, int iter, int duration);
static void set_nofork_info (TestResult * tr);
static char *pass_msg (void);

#if defined(HAVE_FORK) && HAVE_FORK==1
static TestResult *tcase_run_tfun_fork (SRunner * sr, TCase * tc, TF * tf,
    int i);
static TestResult *receive_result_info_fork (const char *tcname,
    const char *tname, int iter,
    int status, int expected_signal, signed char allowed_exit_value);
static void set_fork_info (TestResult * tr, int status, int expected_signal,
    signed char allowed_exit_value);
static char *signal_msg (int sig);
static char *signal_error_msg (int signal_received, int signal_expected);
static char *exit_msg (int exitstatus);
static int waserror (int status, int expected_signal);

static int alarm_received;
static pid_t group_pid;
static struct sigaction sigint_old_action;
static struct sigaction sigterm_old_action;

static void CK_ATTRIBUTE_UNUSED
sig_handler (int sig_nr)
{
  switch (sig_nr) {
    case SIGALRM:
      alarm_received = 1;
      killpg (group_pid, SIGKILL);
      break;
    case SIGTERM:
    case SIGINT:
    {
      pid_t own_group_pid;
      int child_sig = SIGTERM;

      if (sig_nr == SIGINT) {
        child_sig = SIGKILL;
        sigaction (SIGINT, &sigint_old_action, NULL);
      } else {
        sigaction (SIGTERM, &sigterm_old_action, NULL);
      }

      killpg (group_pid, child_sig);

      /* POSIX says that calling killpg(0)
       * does not necessarily mean to call it on the callers
       * group pid! */
      own_group_pid = getpgrp ();
      killpg (own_group_pid, sig_nr);
      break;
    }
    default:
      eprintf ("Unhandled signal: %d", __FILE__, __LINE__, sig_nr);
      break;
  }
}
#endif /* HAVE_FORK */

#define MSG_LEN 100

static void
srunner_run_init (SRunner * sr, enum print_output print_mode)
{
  set_fork_status (srunner_fork_status (sr));
  setup_messaging ();
  srunner_init_logging (sr, print_mode);
  log_srunner_start (sr);
}

static void
srunner_run_end (SRunner * sr, enum print_output CK_ATTRIBUTE_UNUSED print_mode)
{
  log_srunner_end (sr);
  srunner_end_logging (sr);
  teardown_messaging ();
  set_fork_status (CK_FORK);
}

static void
srunner_iterate_suites (SRunner * sr,
    const char *sname, const char *tcname,
    const char *include_tags,
    const char *exclude_tags, enum print_output CK_ATTRIBUTE_UNUSED print_mode)
{
  List *include_tag_lst;
  List *exclude_tag_lst;
  List *slst;
  List *tcl;
  TCase *tc;

  slst = sr->slst;

  include_tag_lst = tag_string_to_list (include_tags);
  exclude_tag_lst = tag_string_to_list (exclude_tags);

  for (check_list_front (slst); !check_list_at_end (slst);
      check_list_advance (slst)) {
    Suite *s = (Suite *) check_list_val (slst);

    if (((sname != NULL) && (strcmp (sname, s->name) != 0))
        || ((tcname != NULL) && (!suite_tcase (s, tcname))))
      continue;

    log_suite_start (sr, s);

    tcl = s->tclst;

    for (check_list_front (tcl); !check_list_at_end (tcl);
        check_list_advance (tcl)) {
      tc = (TCase *) check_list_val (tcl);

      if ((tcname != NULL) && (strcmp (tcname, tc->name) != 0)) {
        continue;
      }
      if (include_tags != NULL) {
        if (!tcase_matching_tag (tc, include_tag_lst)) {
          continue;
        }
      }
      if (exclude_tags != NULL) {
        if (tcase_matching_tag (tc, exclude_tag_lst)) {
          continue;
        }
      }

      srunner_run_tcase (sr, tc);
    }

    log_suite_end (sr, s);
  }

  check_list_apply (include_tag_lst, free);
  check_list_apply (exclude_tag_lst, free);
  check_list_free (include_tag_lst);
  check_list_free (exclude_tag_lst);
}

static void
srunner_iterate_tcase_tfuns (SRunner * sr, TCase * tc)
{
  List *tfl;
  TF *tfun;
  TestResult *tr = NULL;

  tfl = tc->tflst;

  for (check_list_front (tfl); !check_list_at_end (tfl);
      check_list_advance (tfl)) {
    int i;

    tfun = (TF *) check_list_val (tfl);

    for (i = tfun->loop_start; i < tfun->loop_end; i++) {
      log_test_start (sr, tc, tfun);
      switch (srunner_fork_status (sr)) {
        case CK_FORK:
#if defined(HAVE_FORK) && HAVE_FORK==1
          tr = tcase_run_tfun_fork (sr, tc, tfun, i);
#else /* HAVE_FORK */
          eprintf ("This version does not support fork", __FILE__, __LINE__);
#endif /* HAVE_FORK */
          break;
        case CK_NOFORK:
          tr = tcase_run_tfun_nofork (sr, tc, tfun, i);
          break;
        case CK_FORK_GETENV:
        default:
          eprintf ("Bad fork status in SRunner", __FILE__, __LINE__);
      }

      if (NULL != tr) {
        srunner_add_failure (sr, tr);
        log_test_end (sr, tr);
      }
    }
  }
}

static void
srunner_add_failure (SRunner * sr, TestResult * tr)
{
  check_list_add_end (sr->resultlst, tr);
  sr->stats->n_checked++;       /* count checks during setup, test, and teardown */
  if (tr->rtype == CK_FAILURE)
    sr->stats->n_failed++;
  else if (tr->rtype == CK_ERROR)
    sr->stats->n_errors++;

}

static TestResult *
srunner_run_setup (List * fixture_list, enum fork_status fork_usage,
    const char *test_name, const char *setup_name)
{
  TestResult *tr = NULL;
  Fixture *setup_fixture;

  if (fork_usage == CK_FORK) {
    send_ctx_info (CK_CTX_SETUP);
  }

  for (check_list_front (fixture_list); !check_list_at_end (fixture_list);
      check_list_advance (fixture_list)) {
    setup_fixture = (Fixture *) check_list_val (fixture_list);

    if (fork_usage == CK_NOFORK) {
      send_ctx_info (CK_CTX_SETUP);

      if (0 == setjmp (error_jmp_buffer)) {
        setup_fixture->fun ();
      }

      /* Stop the setup and return the failure in nofork mode. */
      tr = receive_result_info_nofork (test_name, setup_name, 0, -1);
      if (tr->rtype != CK_PASS) {
        break;
      }

      free (tr->file);
      free (tr->msg);
      free (tr);
      tr = NULL;
    } else {
      setup_fixture->fun ();
    }
  }

  return tr;
}

static int
srunner_run_unchecked_setup (SRunner * sr, TCase * tc)
{
  TestResult *tr = NULL;
  int rval = 1;

  set_fork_status (CK_NOFORK);
  tr = srunner_run_setup (tc->unch_sflst, CK_NOFORK, tc->name,
      "unchecked_setup");
  set_fork_status (srunner_fork_status (sr));

  if (tr != NULL && tr->rtype != CK_PASS) {
    srunner_add_failure (sr, tr);
    rval = 0;
  }

  return rval;
}

static TestResult *
tcase_run_checked_setup (SRunner * sr, TCase * tc)
{
  TestResult *tr = srunner_run_setup (tc->ch_sflst, srunner_fork_status (sr),
      tc->name, "checked_setup");

  return tr;
}

static void
srunner_run_teardown (List * fixture_list, enum fork_status fork_usage)
{
  Fixture *fixture;

  for (check_list_front (fixture_list); !check_list_at_end (fixture_list);
      check_list_advance (fixture_list)) {
    fixture = (Fixture *) check_list_val (fixture_list);
    send_ctx_info (CK_CTX_TEARDOWN);

    if (fork_usage == CK_NOFORK) {
      if (0 == setjmp (error_jmp_buffer)) {
        fixture->fun ();
      } else {
        /* Abort the remaining teardowns */
        break;
      }
    } else {
      fixture->fun ();
    }
  }
}

static void
srunner_run_unchecked_teardown (SRunner * sr, TCase * tc)
{
  srunner_run_teardown (tc->unch_tflst, srunner_fork_status (sr));
}

static void
tcase_run_checked_teardown (TCase * tc)
{
  srunner_run_teardown (tc->ch_tflst, CK_NOFORK);
}

static void
srunner_run_tcase (SRunner * sr, TCase * tc)
{
  if (srunner_run_unchecked_setup (sr, tc)) {
    srunner_iterate_tcase_tfuns (sr, tc);
    srunner_run_unchecked_teardown (sr, tc);
  }
}

static TestResult *
tcase_run_tfun_nofork (SRunner * sr, TCase * tc, TF * tfun, int i)
{
  TestResult *tr;
  struct timespec ts_start = { 0, 0 }, ts_end = {
  0, 0};

  tr = tcase_run_checked_setup (sr, tc);
  if (tr == NULL) {
    clock_gettime (check_get_clockid (), &ts_start);
    if (0 == setjmp (error_jmp_buffer)) {
      tfun->fn (i);
    }
    clock_gettime (check_get_clockid (), &ts_end);
    tcase_run_checked_teardown (tc);
    return receive_result_info_nofork (tc->name, tfun->name, i,
        DIFF_IN_USEC (ts_start, ts_end));
  }

  return tr;
}

static TestResult *
receive_result_info_nofork (const char *tcname,
    const char *tname, int iter, int duration)
{
  TestResult *tr;

  tr = receive_test_result (0);
  if (tr == NULL) {
    eprintf ("Failed to receive test result", __FILE__, __LINE__);
  } else {
    tr->tcname = tcname;
    tr->tname = tname;
    tr->iter = iter;
    tr->duration = duration;
    set_nofork_info (tr);
  }

  return tr;
}

static void
set_nofork_info (TestResult * tr)
{
  if (tr->msg == NULL) {
    tr->rtype = CK_PASS;
    tr->msg = pass_msg ();
  } else {
    tr->rtype = CK_FAILURE;
  }
}

static char *
pass_msg (void)
{
  return strdup ("Passed");
}

#if defined(HAVE_FORK) && HAVE_FORK==1
static TestResult *
tcase_run_tfun_fork (SRunner * sr, TCase * tc, TF * tfun, int i)
{
  pid_t pid_w;
  pid_t pid;
  int status = 0;
  struct timespec ts_start = { 0, 0 }, ts_end = {
  0, 0};

  timer_t timerid;
  struct itimerspec timer_spec;
  TestResult *tr;


  pid = fork ();
  if (pid == -1)
    eprintf ("Error in call to fork:", __FILE__, __LINE__ - 2);
  if (pid == 0) {
    setpgid (0, 0);
    group_pid = getpgrp ();
    tr = tcase_run_checked_setup (sr, tc);
    free (tr);
    clock_gettime (check_get_clockid (), &ts_start);
    tfun->fn (i);
    clock_gettime (check_get_clockid (), &ts_end);
    tcase_run_checked_teardown (tc);
    send_duration_info (DIFF_IN_USEC (ts_start, ts_end));
    exit (EXIT_SUCCESS);
  } else {
    group_pid = pid;
  }

  alarm_received = 0;

  if (timer_create (check_get_clockid (),
          NULL /* fire SIGALRM if timer expires */ ,
          &timerid) == 0) {
    /* Set the timer to fire once */
    timer_spec.it_value = tc->timeout;
    timer_spec.it_interval.tv_sec = 0;
    timer_spec.it_interval.tv_nsec = 0;
    if (timer_settime (timerid, 0, &timer_spec, NULL) == 0) {
      do {
        pid_w = waitpid (pid, &status, 0);
      }
      while (pid_w == -1);
    } else {
      eprintf ("Error in call to timer_settime:", __FILE__, __LINE__);
    }

    /* If the timer has not fired, disable it */
    timer_delete (timerid);
  } else {
    eprintf ("Error in call to timer_create:", __FILE__, __LINE__);
  }

  killpg (pid, SIGKILL);        /* Kill remaining processes. */

  return receive_result_info_fork (tc->name, tfun->name, i, status,
      tfun->signal, tfun->allowed_exit_value);
}

static TestResult *
receive_result_info_fork (const char *tcname,
    const char *tname,
    int iter, int status, int expected_signal, signed char allowed_exit_value)
{
  TestResult *tr;

  tr = receive_test_result (waserror (status, expected_signal));
  if (tr == NULL) {
    eprintf ("Failed to receive test result", __FILE__, __LINE__);
  } else {
    tr->tcname = tcname;
    tr->tname = tname;
    tr->iter = iter;
    set_fork_info (tr, status, expected_signal, allowed_exit_value);
  }

  return tr;
}

static void
set_fork_info (TestResult * tr, int status, int signal_expected,
    signed char allowed_exit_value)
{
  int was_sig = WIFSIGNALED (status);
  int was_exit = WIFEXITED (status);
  signed char exit_status = WEXITSTATUS (status);
  int signal_received = WTERMSIG (status);

  if (was_sig) {
    if (signal_expected == signal_received) {
      if (alarm_received) {
        /* Got alarm instead of signal */
        tr->rtype = CK_ERROR;
        if (tr->msg != NULL) {
          free (tr->msg);
        }
        tr->msg = signal_error_msg (signal_received, signal_expected);
      } else {
        tr->rtype = CK_PASS;
        if (tr->msg != NULL) {
          free (tr->msg);
        }
        tr->msg = pass_msg ();
      }
    } else if (signal_expected != 0) {
      /* signal received, but not the expected one */
      tr->rtype = CK_ERROR;
      if (tr->msg != NULL) {
        free (tr->msg);
      }
      tr->msg = signal_error_msg (signal_received, signal_expected);
    } else {
      /* signal received and none expected */
      tr->rtype = CK_ERROR;
      if (tr->msg != NULL) {
        free (tr->msg);
      }
      tr->msg = signal_msg (signal_received);
    }
  } else if (signal_expected == 0) {
    if (was_exit && exit_status == allowed_exit_value) {
      tr->rtype = CK_PASS;
      if (tr->msg != NULL) {
        free (tr->msg);
      }
      tr->msg = pass_msg ();
    } else if (was_exit && exit_status != allowed_exit_value) {
      if (tr->msg == NULL) {    /* early exit */
        tr->rtype = CK_ERROR;
        tr->msg = exit_msg (exit_status);
      } else {
        tr->rtype = CK_FAILURE;
      }
    }
  } else {                      /* a signal was expected and none raised */
    if (was_exit) {
      if (tr->msg != NULL) {
        free (tr->msg);
      }
      tr->msg = exit_msg (exit_status);
      tr->rtype = CK_FAILURE;   /* normal exit status */
    }
  }
}

static char *
signal_msg (int signal)
{
  char *msg = (char *) emalloc (MSG_LEN);       /* free'd by caller */

  if (alarm_received) {
    snprintf (msg, MSG_LEN, "Test timeout expired");
  } else {
    snprintf (msg, MSG_LEN, "Received signal %d (%s)",
        signal, strsignal (signal));
  }
  return msg;
}

static char *
signal_error_msg (int signal_received, int signal_expected)
{
  char *sig_r_str;
  char *sig_e_str;
  char *msg = (char *) emalloc (MSG_LEN);       /* free'd by caller */

  sig_r_str = strdup (strsignal (signal_received));
  sig_e_str = strdup (strsignal (signal_expected));
  if (alarm_received) {
    snprintf (msg, MSG_LEN,
        "Test timeout expired, expected signal %d (%s)",
        signal_expected, sig_e_str);
  } else {
    snprintf (msg, MSG_LEN, "Received signal %d (%s), expected %d (%s)",
        signal_received, sig_r_str, signal_expected, sig_e_str);
  }
  free (sig_r_str);
  free (sig_e_str);
  return msg;
}

static char *
exit_msg (int exitval)
{
  char *msg = (char *) emalloc (MSG_LEN);       /* free'd by caller */

  snprintf (msg, MSG_LEN, "Early exit with return value %d", exitval);
  return msg;
}

static int
waserror (int status, int signal_expected)
{
  int was_sig = WIFSIGNALED (status);
  int was_exit = WIFEXITED (status);
  int exit_status = WEXITSTATUS (status);
  int signal_received = WTERMSIG (status);

  return ((was_sig && (signal_received != signal_expected)) ||
      (was_exit && exit_status != 0));
}
#endif /* HAVE_FORK */

enum fork_status
srunner_fork_status (SRunner * sr)
{
  if (sr->fstat == CK_FORK_GETENV) {
    char *env = getenv ("CK_FORK");

    if (env == NULL)
#if defined(HAVE_FORK) && HAVE_FORK==1
      return CK_FORK;
#else
      return CK_NOFORK;
#endif
    if (strcmp (env, "no") == 0)
      return CK_NOFORK;
    else {
#if defined(HAVE_FORK) && HAVE_FORK==1
      return CK_FORK;
#else /* HAVE_FORK */
      eprintf ("This version does not support fork", __FILE__, __LINE__);
      /* Ignoring, as Check is not compiled with fork support. */
      return CK_NOFORK;
#endif /* HAVE_FORK */
    }
  } else
    return sr->fstat;
}

void
srunner_set_fork_status (SRunner * sr, enum fork_status fstat)
{
#if !defined(HAVE_FORK) || HAVE_FORK==0
  /* If fork() is unavailable, do not allow a fork mode to be set */
  if (fstat != CK_NOFORK) {
    eprintf ("This version does not support fork", __FILE__, __LINE__);
    /* Overriding, as Check is not compiled with fork support. */
    fstat = CK_NOFORK;
  }
#endif /* ! HAVE_FORK */
  sr->fstat = fstat;
}

void
srunner_run_all (SRunner * sr, enum print_output print_mode)
{
  srunner_run (sr, NULL,        /* All test suites.  */
      NULL,                     /* All test cases.   */
      print_mode);
}

void
srunner_run_tagged (SRunner * sr, const char *sname, const char *tcname,
    const char *include_tags, const char *exclude_tags,
    enum print_output print_mode)
{
#if defined(HAVE_SIGACTION) && defined(HAVE_FORK)
  static struct sigaction sigalarm_old_action;
  static struct sigaction sigalarm_new_action;
  static struct sigaction sigint_new_action;
  static struct sigaction sigterm_new_action;
#endif /* HAVE_SIGACTION && HAVE_FORK */

  /*  Get the selected test suite and test case from the
     environment.  */
  if (!tcname)
    tcname = getenv ("CK_RUN_CASE");
  if (!sname)
    sname = getenv ("CK_RUN_SUITE");
  if (!include_tags)
    include_tags = getenv ("CK_INCLUDE_TAGS");
  if (!exclude_tags)
    exclude_tags = getenv ("CK_EXCLUDE_TAGS");

  if (sr == NULL)
    return;
  if (print_mode >= CK_LAST) {
    eprintf ("Bad print_mode argument to srunner_run_all: %d",
        __FILE__, __LINE__, print_mode);
  }
#if defined(HAVE_SIGACTION) && defined(HAVE_FORK)
  memset (&sigalarm_new_action, 0, sizeof (sigalarm_new_action));
  sigalarm_new_action.sa_handler = sig_handler;
  sigaction (SIGALRM, &sigalarm_new_action, &sigalarm_old_action);

  memset (&sigint_new_action, 0, sizeof (sigint_new_action));
  sigint_new_action.sa_handler = sig_handler;
  sigaction (SIGINT, &sigint_new_action, &sigint_old_action);

  memset (&sigterm_new_action, 0, sizeof (sigterm_new_action));
  sigterm_new_action.sa_handler = sig_handler;
  sigaction (SIGTERM, &sigterm_new_action, &sigterm_old_action);
#endif /* HAVE_SIGACTION && HAVE_FORK */
  srunner_run_init (sr, print_mode);
  srunner_iterate_suites (sr, sname, tcname, include_tags, exclude_tags,
      print_mode);
  srunner_run_end (sr, print_mode);
#if defined(HAVE_SIGACTION) && defined(HAVE_FORK)
  sigaction (SIGALRM, &sigalarm_old_action, NULL);
  sigaction (SIGINT, &sigint_old_action, NULL);
  sigaction (SIGTERM, &sigterm_old_action, NULL);
#endif /* HAVE_SIGACTION && HAVE_FORK */
}

void
srunner_run (SRunner * sr, const char *sname, const char *tcname,
    enum print_output print_mode)
{
  srunner_run_tagged (sr, sname, tcname, NULL, NULL, print_mode);
}

pid_t
check_fork (void)
{
#if defined(HAVE_FORK) && HAVE_FORK==1
  pid_t pid = fork ();

  /* Set the process to a process group to be able to kill it easily. */
  if (pid >= 0) {
    setpgid (pid, group_pid);
  }
  return pid;
#else /* HAVE_FORK */
  eprintf ("This version does not support fork", __FILE__, __LINE__);
  return 0;
#endif /* HAVE_FORK */
}

void
check_waitpid_and_exit (pid_t pid CK_ATTRIBUTE_UNUSED)
{
#if defined(HAVE_FORK) && HAVE_FORK==1
  pid_t pid_w;
  int status;

  if (pid > 0) {
    do {
      pid_w = waitpid (pid, &status, 0);
    }
    while (pid_w == -1);
    if (waserror (status, 0)) {
      exit (EXIT_FAILURE);
    }
  }
  exit (EXIT_SUCCESS);
#else /* HAVE_FORK */
  eprintf ("This version does not support fork", __FILE__, __LINE__);
  /* Ignoring, as Check is not compiled with fork support. */
  exit (EXIT_FAILURE);
#endif /* HAVE_FORK */
}
