#ifdef GOOGLETEST_H__
#error You must not include this file twice.
#endif
#define GOOGLETEST_H__

#include <ctype.h>
#include <setjmp.h>
#include <time.h>

#include <map>
#include <sstream>
#include <string>
#include <vector>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include "base/commandlineflags.h"

using std::map;
using std::string;
using std::vector;

DEFINE_string(test_tmpdir, "/tmp", "Dir we use for temp files");
DEFINE_string(test_srcdir, ".",
              "Source-dir root, needed to find glog_unittest_flagfile");
DEFINE_int32(benchmark_iters, 100000000, "Number of iterations per benchmark");

_START_GOOGLE_NAMESPACE_

extern void (*g_logging_fail_func)();

// The following is some bare-bones testing infrastructure

#define EXPECT_TRUE(cond)                               \
  do {                                                  \
    if (!(cond)) {                                      \
      fprintf(stderr, "Check failed: %s\n", #cond);     \
      exit(1);                                          \
    }                                                   \
  } while (0)

#define EXPECT_FALSE(cond)  EXPECT_TRUE(!(cond))

#define EXPECT_OP(op, val1, val2)                                       \
  do {                                                                  \
    if (!((val1) op (val2))) {                                          \
      fprintf(stderr, "Check failed: %s %s %s\n", #val1, #op, #val2);   \
      exit(1);                                                          \
    }                                                                   \
  } while (0)

#define EXPECT_EQ(val1, val2)  EXPECT_OP(==, val1, val2)
#define EXPECT_NE(val1, val2)  EXPECT_OP(!=, val1, val2)
#define EXPECT_GT(val1, val2)  EXPECT_OP(>, val1, val2)
#define EXPECT_LT(val1, val2)  EXPECT_OP(<, val1, val2)

#define EXPECT_NAN(arg)                                         \
  do {                                                          \
    if (!isnan(arg)) {                                          \
      fprintf(stderr, "Check failed: isnan(%s)\n", #arg);       \
      exit(1);                                                  \
    }                                                           \
  } while (0)

#define EXPECT_INF(arg)                                         \
  do {                                                          \
    if (!isinf(arg)) {                                          \
      fprintf(stderr, "Check failed: isinf(%s)\n", #arg);       \
      exit(1);                                                  \
    }                                                           \
  } while (0)

#define EXPECT_DOUBLE_EQ(val1, val2)                                    \
  do {                                                                  \
    if (((val1) < (val2) - 0.001 || (val1) > (val2) + 0.001)) {         \
      fprintf(stderr, "Check failed: %s == %s\n", #val1, #val2);        \
      exit(1);                                                          \
    }                                                                   \
  } while (0)

#define EXPECT_STREQ(val1, val2)                                        \
  do {                                                                  \
    if (strcmp((val1), (val2)) != 0) {                                  \
      fprintf(stderr, "Check failed: streq(%s, %s)\n", #val1, #val2);   \
      exit(1);                                                          \
    }                                                                   \
  } while (0)

static bool g_called_abort;
static jmp_buf g_jmp_buf;
static void CalledAbort() {
  g_called_abort = true;
  longjmp(g_jmp_buf, 1);
}

#define ASSERT_DEATH(fn, msg)                                           \
  do {                                                                  \
    g_called_abort = false;                                             \
    /* in logging.cc */                                                 \
    void (*original_logging_fail_func)() = g_logging_fail_func;         \
    g_logging_fail_func = &CalledAbort;                                 \
    if (!setjmp(g_jmp_buf)) fn;                                         \
    /* set back to their default */                                     \
    g_logging_fail_func = original_logging_fail_func;                   \
    if (!g_called_abort) {                                              \
      fprintf(stderr, "Function didn't die (%s): %s\n", msg, #fn);      \
      exit(1);                                                          \
    }                                                                   \
  } while (0)

#ifdef NDEBUG
#define ASSERT_DEBUG_DEATH(fn, msg)
#else
#define ASSERT_DEBUG_DEATH(fn, msg) ASSERT_DEATH(fn, msg)
#endif  // NDEBUG

vector<void (*)()> g_testlist;  // the tests to run

#define TEST(a, b)                                      \
  struct Test_##a##_##b {                               \
    Test_##a##_##b() { g_testlist.push_back(&Run); }    \
    static void Run() { FlagSaver fs; RunTest(); }      \
    static void RunTest();                              \
  };                                                    \
  static Test_##a##_##b g_test_##a##_##b;               \
  void Test_##a##_##b::RunTest()


static int RUN_ALL_TESTS() {
  vector<void (*)()>::const_iterator it;
  for (it = g_testlist.begin(); it != g_testlist.end(); ++it) {
    (*it)();
  }
  fprintf(stderr, "Passed %d tests\n\nPASS\n", (int)g_testlist.size());
  return 0;
}

// Benchmark tools.

#define BENCHMARK(n) static BenchmarkRegisterer __benchmark_ ## n (#n, &n);

map<string, void (*)(int)> g_benchlist;  // the benchmarks to run

class BenchmarkRegisterer {
 public:
  BenchmarkRegisterer(const char* name, void (*function)(int iters)) {
    EXPECT_TRUE(g_benchlist.insert(std::make_pair(name, function)).second);
  }
};

static void RunSpecifiedBenchmarks() {
  int iter_cnt = FLAGS_benchmark_iters;
  puts("Benchmark\tTime(ns)\tIterations");
  for (map<string, void (*)(int)>::const_iterator iter = g_benchlist.begin();
       iter != g_benchlist.end();
       ++iter) {
    clock_t start = clock();
    iter->second(iter_cnt);
    double elapsed_ns =
        ((double)clock() - start) / CLOCKS_PER_SEC * 1000*1000*1000;
    printf("%s\t%8.2lf\t%10d\n",
           iter->first.c_str(), elapsed_ns / iter_cnt, iter_cnt);
  }
  puts("");
}

// ----------------------------------------------------------------------
// Golden file functions
// ----------------------------------------------------------------------

class CapturedStream {
 public:
  CapturedStream(int fd, const string & filename) :
    fd_(fd),
    uncaptured_fd_(-1),
    filename_(filename) {
    Capture();
  }

  ~CapturedStream() {
    if (uncaptured_fd_ != -1) {
      CHECK(close(uncaptured_fd_) != -1);
    }
  }

  // Start redirecting output to a file
  void Capture() {
    // Keep original stream for later
    CHECK(uncaptured_fd_ == -1) << ", Stream " << fd_ << " already captured!";
    uncaptured_fd_ = dup(fd_);
    CHECK(uncaptured_fd_ != -1);

    // Open file to save stream to
    int cap_fd = open(filename_.c_str(),
                      O_CREAT | O_TRUNC | O_WRONLY,
                      S_IRUSR | S_IWUSR);
    CHECK(cap_fd != -1);

    // Send stdout/stderr to this file
    fflush(NULL);
    CHECK(dup2(cap_fd, fd_) != -1);
    CHECK(close(cap_fd) != -1);
  }

  // Remove output redirection
  void StopCapture() {
    // Restore original stream
    if (uncaptured_fd_ != -1) {
      fflush(NULL);
      CHECK(dup2(uncaptured_fd_, fd_) != -1);
    }
  }

  const string & filename() const { return filename_; }

 private:
  int fd_;             // file descriptor being captured
  int uncaptured_fd_;  // where the stream was originally being sent to
  string filename_;    // file where stream is being saved
};
static CapturedStream * s_captured_streams[STDERR_FILENO+1];
// Redirect a file descriptor to a file.
//   fd       - Should be STDOUT_FILENO or STDERR_FILENO
//   filename - File where output should be stored
static void CaptureTestOutput(int fd, const string & filename) {
  CHECK((fd == STDOUT_FILENO) || (fd == STDERR_FILENO));
  CHECK(s_captured_streams[fd] == NULL);
  s_captured_streams[fd] = new CapturedStream(fd, filename);
}
static void CaptureTestStderr() {
  CaptureTestOutput(STDERR_FILENO, FLAGS_test_tmpdir + "/captured.err");
}
// Return the size (in bytes) of a file
static size_t GetFileSize(FILE * file) {
  fseek(file, 0, SEEK_END);
  return static_cast<size_t>(ftell(file));
}
// Read the entire content of a file as a string
static string ReadEntireFile(FILE * file) {
  const size_t file_size = GetFileSize(file);
  char * const buffer = new char[file_size];

  size_t bytes_last_read = 0;  // # of bytes read in the last fread()
  size_t bytes_read = 0;       // # of bytes read so far

  fseek(file, 0, SEEK_SET);

  // Keep reading the file until we cannot read further or the
  // pre-determined file size is reached.
  do {
    bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file);
    bytes_read += bytes_last_read;
  } while (bytes_last_read > 0 && bytes_read < file_size);

  const string content = string(buffer, buffer+bytes_read);
  delete[] buffer;

  return content;
}
// Get the captured stdout (when fd is STDOUT_FILENO) or stderr (when
// fd is STDERR_FILENO) as a string
static string GetCapturedTestOutput(int fd) {
  CHECK(fd == STDOUT_FILENO || fd == STDERR_FILENO);
  CapturedStream * const cap = s_captured_streams[fd];
  CHECK(cap)
    << ": did you forget CaptureTestStdout() or CaptureTestStderr()?";

  // Make sure everything is flushed.
  cap->StopCapture();

  // Read the captured file.
  FILE * const file = fopen(cap->filename().c_str(), "r");
  const string content = ReadEntireFile(file);
  fclose(file);

  delete cap;
  s_captured_streams[fd] = NULL;

  return content;
}
// Get the captured stderr of a test as a string.
static string GetCapturedTestStderr() {
  return GetCapturedTestOutput(STDERR_FILENO);
}

// Check if the string is [IWEF](\d{4}|DATE)
static bool IsLoggingPrefix(const string& s) {
  if (s.size() != 5) return false;
  if (!strchr("IWEF", s[0])) return false;
  for (int i = 1; i <= 4; ++i) {
    if (!isdigit(s[i]) && s[i] != "DATE"[i-1]) return false;
  }
  return true;
}

// Convert log output into normalized form.
//
// Example:
//     I0102 030405 logging_unittest.cc:345] RAW: vlog -1
//  => IDATE TIME__ logging_unittest.cc:LINE] RAW: vlog -1
static string MungeLine(const string& line) {
  std::istringstream iss(line);
  string before, logcode_date, time, thread_lineinfo;
  iss >> logcode_date;
  while (!IsLoggingPrefix(logcode_date)) {
    before += " " + logcode_date;
    if (iss.eof()) {
      // We cannot find the header of log output.
      return before;
    }
    iss >> logcode_date;
  }
  if (!before.empty()) before += " ";
  iss >> time;
  CHECK_EQ(6, time.size());
  iss >> thread_lineinfo;
  CHECK(!thread_lineinfo.empty());
  if (thread_lineinfo[thread_lineinfo.size() - 1] != ']') {
    // We found thread ID.
    string tmp;
    iss >> tmp;
    CHECK(!tmp.empty());
    CHECK_EQ(']', tmp[tmp.size() - 1]);
    thread_lineinfo = "THREADID " + tmp;
  }
  size_t index = thread_lineinfo.find(':');
  CHECK_NE(string::npos, index);
  thread_lineinfo = thread_lineinfo.substr(0, index+1) + "LINE]";
  string rest;
  std::getline(iss, rest);
  return (before + logcode_date[0] + "DATE TIME__ " + thread_lineinfo +
          MungeLine(rest));
}

static void StringReplace(string* str,
                          const string& oldsub,
                          const string& newsub) {
  size_t pos = str->find(oldsub);
  if (pos != string::npos) {
    str->replace(pos, oldsub.size(), newsub.c_str());
  }
}

static string Munge(const string& filename) {
  FILE* fp = fopen(filename.c_str(), "rb");
  CHECK(fp != NULL) << filename << ": couldn't open";
  char buf[4096];
  string result;
  while (fgets(buf, 4095, fp)) {
    string line = MungeLine(buf);
    char null_str[256];
    sprintf(null_str, "%p", NULL);
    StringReplace(&line, "__NULLP__", null_str);

    char errmsg_buf[100];
    posix_strerror_r(0, errmsg_buf, sizeof(errmsg_buf));
    if (*errmsg_buf == '\0') {
      // MacOSX 10.4 and FreeBSD return empty string for errno=0.
      // In such case, the we need to remove an extra space.
      StringReplace(&line, "__SUCCESS__ ", "");
    } else {
      StringReplace(&line, "__SUCCESS__", errmsg_buf);
    }
    StringReplace(&line, "__ENOENT__", strerror(ENOENT));
    StringReplace(&line, "__EINTR__", strerror(EINTR));
    StringReplace(&line, "__ENXIO__", strerror(ENXIO));
    StringReplace(&line, "__ENOEXEC__", strerror(ENOEXEC));
    result += line + "\n";
  }
  fclose(fp);
  return result;
}

static void WriteToFile(const string& body, const string& file) {
  FILE* fp = fopen(file.c_str(), "wb");
  fwrite(body.data(), 1, body.size(), fp);
  fclose(fp);
}

static bool MungeAndDiffTestStderr(const string& golden_filename) {
  CapturedStream* cap = s_captured_streams[STDERR_FILENO];
  CHECK(cap) << ": did you forget CaptureTestStderr()?";

  cap->StopCapture();

  // Run munge
  const string captured = Munge(cap->filename());
  const string golden = Munge(golden_filename);
  if (captured != golden) {
    fprintf(stderr,
            "Test with golden file failed. We'll try to show the diff:\n");
    string munged_golden = golden_filename + ".munged";
    WriteToFile(golden, munged_golden);
    string munged_captured = cap->filename() + ".munged";
    WriteToFile(captured, munged_captured);
    string diffcmd("diff -u " + munged_golden + " " + munged_captured);
    if (system(diffcmd.c_str()) != 0) {
      fprintf(stderr, "diff command was failed.\n");
    }
    unlink(munged_golden.c_str());
    unlink(munged_captured.c_str());
    return false;
  }
  LOG(INFO) << "Diff was successful";
  return true;
}

// Save flags used from logging_unittest.cc.
#ifndef HAVE_LIB_GFLAGS
struct FlagSaver {
  FlagSaver()
      : v_(FLAGS_v),
        stderrthreshold_(FLAGS_stderrthreshold),
        logtostderr_(FLAGS_logtostderr),
        alsologtostderr_(FLAGS_alsologtostderr) {}
  ~FlagSaver() {
    FLAGS_v = v_;
    FLAGS_stderrthreshold = stderrthreshold_;
    FLAGS_logtostderr = logtostderr_;
    FLAGS_alsologtostderr = alsologtostderr_;
  }
  int v_;
  int stderrthreshold_;
  bool logtostderr_;
  bool alsologtostderr_;
};
#endif

// TODO(hamaji): Make it portable.
class Thread {
 public:
  void SetJoinable(bool joinable) {}
  void Start() {
    pthread_create(&th_, NULL, &Thread::InvokeThread, this);
  }
  void Join() {
    pthread_join(th_, NULL);
  }

 protected:
  virtual void Run() = 0;

 private:
  static void* InvokeThread(void* self) {
    ((Thread*)self)->Run();
    return NULL;
  }

  pthread_t th_;
};

// TODO(hamaji): Make it portable.
static void SleepForMilliseconds(int t) {
  usleep(t * 1000);
}

// Add hook for operator new to ensure there are no memory allocation.

void (*g_new_hook)() = NULL;

_END_GOOGLE_NAMESPACE_

void* operator new(size_t size) {
  if (GOOGLE_NAMESPACE::g_new_hook) {
    GOOGLE_NAMESPACE::g_new_hook();
  }
  return malloc(size);
}

void* operator new[](size_t size) {
  return ::operator new(size);
}

void operator delete(void* p) {
  free(p);
}

void operator delete[](void* p) {
  ::operator delete(p);
}
