// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "p2p/common/testutil.h"

#include <fcntl.h>
#include <glib-object.h>
#include <stdarg.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/xattr.h>

#include <cctype>
#include <cinttypes>
#include <cstdlib>

#include <base/check.h>
#include <base/logging.h>
#include <base/macros.h>
#include <base/strings/string_number_conversions.h>
#include <gtest/gtest.h>

using std::string;

using base::FilePath;

namespace p2p {

namespace testutil {

// This is the message to be displayed if the TimeBombAbort timeout is
// reached.
static const char* time_bomb_abort_message_ = NULL;

TimeBombAbort::TimeBombAbort(int timeout_seconds, const char* message) {
  CHECK(time_bomb_abort_message_ == NULL);
  time_bomb_abort_message_ = message;
  // Install the signal handler keeping the previous one.
  struct sigaction time_bomb_action;
  time_bomb_action.sa_flags = 0;
  time_bomb_action.sa_handler = TimeoutHandler;
  sigaction(SIGALRM, &time_bomb_action, &previous_);
  alarm(timeout_seconds);
}

TimeBombAbort::~TimeBombAbort() {
  // Restore the previous sigaction.
  alarm(0);
  sigaction(SIGALRM, &previous_, NULL);
  time_bomb_abort_message_ = NULL;
}

void TimeBombAbort::TimeoutHandler(int signal) {
  // Does a "best-effort" write.
  const char* msg = "\n\nTimeBombAbort::TimeoutHandler reached.\n";
  ignore_result(write(STDERR_FILENO, msg, strlen(msg)));
  ignore_result(write(STDERR_FILENO, time_bomb_abort_message_,
                      strlen(time_bomb_abort_message_)));
  exit(1);
}

FilePath SetupTestDir(const string& test_name) {
  // Create testing directory
  FilePath ret;
  string dir_name = string("/tmp/p2p-testing-") + test_name + ".XXXXXX";
  char* buf = strdup(dir_name.c_str());
  EXPECT_TRUE(mkdtemp(buf) != NULL);
  ret = FilePath(buf);
  free(buf);
  return ret;
}

void TeardownTestDir(const FilePath& dir_path) {
  // Sanity check
  EXPECT_EQ(0, dir_path.value().find("/tmp/p2p-testing-"));
  EXPECT_COMMAND(0, "rm -rf %s", dir_path.value().c_str());
}

static gboolean RunGMainLoopOnTimeout(gpointer user_data) {
  bool* timeout = static_cast<bool*>(user_data);
  *timeout = true;
  return FALSE;  // Remove timeout source
}

void RunGMainLoopUntil(int timeout_msec,
                       base::RepeatingCallback<bool()> terminate) {
  GMainLoop* loop = g_main_loop_new(NULL, FALSE);
  GMainContext* context = g_main_context_default();

  bool timeout = false;
  guint source_id = g_timeout_add(
      timeout_msec, p2p::testutil::RunGMainLoopOnTimeout, &timeout);

  while (!timeout && (terminate.is_null() || !terminate.Run()))
    g_main_context_iteration(context, TRUE);

  g_source_remove(source_id);
  g_main_loop_unref(loop);
}

int RunGMainLoopMaxIterations(int iterations) {
  int result;
  GMainContext* context = g_main_context_default();
  for (result = 0;
       result < iterations && g_main_context_iteration(context, FALSE);
       result++) {
  }
  return result;
}

size_t FileSize(const FilePath& dir, const string& file_name) {
  struct stat stat_buf;
  FilePath path = dir.Append(file_name);
  if (stat(path.value().c_str(), &stat_buf) != 0) {
    return 0;
  }
  return stat_buf.st_size;
}

void ExpectFileSize(const FilePath& dir,
                    const string& file_name,
                    size_t expected_size) {
  EXPECT_EQ(FileSize(dir, file_name), expected_size);
}

bool SetExpectedFileSize(const FilePath& filename, size_t size) {
  int fd = open(filename.value().c_str(), O_RDWR);
  if (fd == -1)
    return false;

  string decimal_size = base::NumberToString(size);
  if (fsetxattr(fd, "user.cros-p2p-filesize", decimal_size.c_str(),
                decimal_size.size(), 0) != 0) {
    close(fd);
    return false;
  }
  close(fd);
  return true;
}

}  // namespace testutil

}  // namespace p2p
