/*
 * 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.h"

#include <sys/types.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdio.h>

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


/* 'Pipe' is implemented as a temporary file to overcome message
 * volume limitations outlined in bug #482012. This scheme works well
 * with the existing usage wherein the parent does not begin reading
 * until the child has done writing and exited.
 *
 * Pipe life cycle:
 * - The parent creates a tmpfile().
 * - The fork() call has the effect of duplicating the file descriptor
 *   and copying (on write) the FILE* data structures.
 * - The child writes to the file, and its dup'ed file descriptor and
 *   data structures are cleaned up on child process exit.
 * - Before reading, the parent rewind()'s the file to reset both
 *   FILE* and underlying file descriptor location data.
 * - When finished, the parent fclose()'s the FILE*, deleting the
 *   temporary file, per tmpfile()'s semantics.
 *
 * This scheme may break down if the usage changes to asynchronous
 * reading and writing.
 */

static FILE *send_file1;
static char *send_file1_name;
static FILE *send_file2;
static char *send_file2_name;

static FILE *get_pipe (void);
static void setup_pipe (void);
static void teardown_pipe (void);
static TestResult *construct_test_result (RcvMsg * rmsg, int waserror);
static void tr_set_loc_by_ctx (TestResult * tr, enum ck_result_ctx ctx,
    RcvMsg * rmsg);
static FILE *
get_pipe (void)
{
  if (send_file2 != 0) {
    return send_file2;
  }

  if (send_file1 != 0) {
    return send_file1;
  }

  eprintf ("No messaging setup", __FILE__, __LINE__);

  return NULL;
}

void
send_failure_info (const char *msg)
{
  FailMsg fmsg;

  fmsg.msg = strdup (msg);
  ppack (get_pipe (), CK_MSG_FAIL, (CheckMsg *) & fmsg);
  free (fmsg.msg);
}

void
send_duration_info (int duration)
{
  DurationMsg dmsg;

  dmsg.duration = duration;
  ppack (get_pipe (), CK_MSG_DURATION, (CheckMsg *) & dmsg);
}

void
send_loc_info (const char *file, int line)
{
  LocMsg lmsg;

  lmsg.file = strdup (file);
  lmsg.line = line;
  ppack (get_pipe (), CK_MSG_LOC, (CheckMsg *) & lmsg);
  free (lmsg.file);
}

void
send_ctx_info (enum ck_result_ctx ctx)
{
  CtxMsg cmsg;

  cmsg.ctx = ctx;
  ppack (get_pipe (), CK_MSG_CTX, (CheckMsg *) & cmsg);
}

TestResult *
receive_test_result (int waserror)
{
  FILE *fp;
  RcvMsg *rmsg;
  TestResult *result;

  fp = get_pipe ();
  if (fp == NULL) {
    eprintf ("Error in call to get_pipe", __FILE__, __LINE__ - 2);
  }

  rewind (fp);
  rmsg = punpack (fp);

  if (rmsg == NULL) {
    eprintf ("Error in call to punpack", __FILE__, __LINE__ - 4);
  }

  teardown_pipe ();
  setup_pipe ();

  result = construct_test_result (rmsg, waserror);
  rcvmsg_free (rmsg);
  return result;
}

static void
tr_set_loc_by_ctx (TestResult * tr, enum ck_result_ctx ctx, RcvMsg * rmsg)
{
  if (ctx == CK_CTX_TEST) {
    tr->file = rmsg->test_file;
    tr->line = rmsg->test_line;
    rmsg->test_file = NULL;
    rmsg->test_line = -1;
  } else {
    tr->file = rmsg->fixture_file;
    tr->line = rmsg->fixture_line;
    rmsg->fixture_file = NULL;
    rmsg->fixture_line = -1;
  }
}

static TestResult *
construct_test_result (RcvMsg * rmsg, int waserror)
{
  TestResult *tr;

  if (rmsg == NULL)
    return NULL;

  tr = tr_create ();

  if (rmsg->msg != NULL || waserror) {
    tr->ctx = rmsg->lastctx;
    tr->msg = rmsg->msg;
    rmsg->msg = NULL;
    tr_set_loc_by_ctx (tr, tr->ctx, rmsg);
  } else if (rmsg->lastctx == CK_CTX_SETUP) {
    tr->ctx = CK_CTX_SETUP;
    tr->msg = NULL;
    tr_set_loc_by_ctx (tr, CK_CTX_SETUP, rmsg);
  } else {
    tr->ctx = CK_CTX_TEST;
    tr->msg = NULL;
    tr->duration = rmsg->duration;
    tr_set_loc_by_ctx (tr, CK_CTX_TEST, rmsg);
  }

  return tr;
}

void
setup_messaging (void)
{
  setup_pipe ();
}

void
teardown_messaging (void)
{
  teardown_pipe ();
}

/**
 * Open a temporary file.
 *
 * If the file could be unlinked upon creation, the name
 * of the file is not returned via 'name'. However, if the
 * file could not be unlinked, the name is returned,
 * expecting the caller to both delete the file and
 * free the 'name' field after the file is closed.
 */
FILE *
open_tmp_file (char **name)
{
  FILE *file = NULL;

  *name = NULL;

#if !HAVE_MKSTEMP
  /* Windows does not like tmpfile(). This is likely because tmpfile()
   * call unlink() on the file before returning it, to make sure the
   * file is deleted when it is closed. The unlink() call also fails
   * on Windows if the file is still open. */
  /* also note that mkstemp is apparently a C90 replacement for tmpfile */
  /* perhaps all we need to do on Windows is set TMPDIR to whatever is
     stored in TEMP for tmpfile to work */
  /* and finally, the "b" from "w+b" is ignored on OS X, not sure about WIN32 */

  file = tmpfile ();
  if (file == NULL) {
    char *tmp = getenv ("TEMP");
    char *tmp_file = tempnam (tmp, "check_");

    /*
     * Note, tempnam is not enough to get a unique name. Between
     * getting the name and opening the file, something else also
     * calling tempnam() could get the same name. It has been observed
     * on MinGW-w64 builds on Wine that this exact thing happens
     * if multiple instances of a unit tests are running concurrently.
     * To prevent two concurrent unit tests from getting the same file,
     * we append the pid to the file. The pid should be unique on the
     * system.
     */
    char *uniq_tmp_file = ck_strdup_printf ("%s.%d", tmp_file, getpid ());

    file = fopen (uniq_tmp_file, "w+b");
    *name = uniq_tmp_file;
    free (tmp_file);
  }
#else
  int fd = -1;
  const char *tmp_dir = getenv ("TEMP");
  if (!tmp_dir) {
    tmp_dir = ".";
  }
  *name = ck_strdup_printf ("%s/check_XXXXXX", tmp_dir);
  if (-1 < (fd = mkstemp (*name))) {
    file = fdopen (fd, "w+b");
    if (0 == unlink (*name) || NULL == file) {
      free (*name);
      *name = NULL;
    }
  }
#endif
  return file;
}

static void
setup_pipe (void)
{
  if (send_file1 == NULL) {
    send_file1 = open_tmp_file (&send_file1_name);
    return;
  }
  if (send_file2 == NULL) {
    send_file2 = open_tmp_file (&send_file2_name);
    return;
  }
  eprintf ("Only one nesting of suite runs supported", __FILE__, __LINE__);
}

static void
teardown_pipe (void)
{
  if (send_file2 != 0) {
    fclose (send_file2);
    send_file2 = 0;
    if (send_file2_name != NULL) {
      unlink (send_file2_name);
      free (send_file2_name);
      send_file2_name = NULL;
    }
  } else if (send_file1 != 0) {
    fclose (send_file1);
    send_file1 = 0;
    if (send_file1_name != NULL) {
      unlink (send_file1_name);
      free (send_file1_name);
      send_file1_name = NULL;
    }
  } else {
    eprintf ("No messaging setup", __FILE__, __LINE__);
  }
}
