// Not sure where to begin with gtest?
//
// What can I test with gtest?
//
// googletest/googletest/docs/primer.md

#include "render.h"
#include "terminal.h"
#include "utils.h"
#include "gtest/gtest.h"
#include <errno.h>
#include <fcntl.h>
#include <string>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#define GTEST_COUT std::cerr << "[          ] [ INFO ]"

struct console_details console;

namespace {

class RenderFixture : public ::testing::Test {
public:
  time_t start;
  int fd;
  const char *filename = "render.testing";

protected:
  virtual void SetUp() {
    console_init(&console);
    start = time(NULL);
    // creat : File is WRITE ONLY.
    fd = creat(filename, S_IRUSR | S_IWUSR);
  }
  virtual void TearDown() {
    if (fd > 0)
      close(fd);
    unlink(filename);
  }
};

TEST_F(RenderFixture, CheckPause) {
  std::string pause( TRIGGER "P1");
  render(fd, pause);
  int elapsed = time(NULL) - start;
  ASSERT_GT(elapsed, 0);
  ASSERT_EQ(elapsed, 1);
}

TEST_F(RenderFixture, CheckPauseTwo) {
  std::string pause( TRIGGER "P2");
  render(fd, pause);
  int elapsed = time(NULL) - start;
  ASSERT_GT(elapsed, 1);
  ASSERT_EQ(elapsed, 2);
}

TEST_F(RenderFixture, ColorTest) {
  ASSERT_GT(fd, 0);
  std::string colors( TRIGGER "C01One" TRIGGER "C02Two" TRIGGER "C03Three" TRIGGER "C04Four");
  render(fd, colors);

  int lfd = open(filename, O_RDONLY);
  char buffer[100];
  int len = read(lfd, buffer, sizeof(buffer));
  if (len == -1) {
    ASSERT_EQ(errno, 0);
  }
  buffer[len] = 0;
  close(lfd);

  GTEST_COUT << "buffer:" << buffer << std::endl;

  ASSERT_EQ(len, 43);
  ASSERT_STREQ(buffer,
               "\x1B[0;34mOne\x1B[0;32mTwo\x1B[0;36mThree\x1B[0;31mFour");
  struct console_details cons;
  console_init(&cons);
  int color_list[4] = {4, 2, 6, 1};
  int color = 0;
  for (int x = 0; x < len; ++x) {
    termchar tc;

    tc = console_char(&cons, buffer[x]);
    if (tc.ansi == COLOR) {
      GTEST_COUT << "Console color:" << cons.fgcolor << std::endl;
      ASSERT_EQ(cons.fgcolor, color_list[color]);
      color++;
    }
  }
  ASSERT_EQ(color, 4);
}

TEST_F(RenderFixture, ColorEffectTest) {
  std::string colors( TRIGGER "S1" TRIGGER "R1\x1b[1;33;44mMEOW!\x1b[0m");
  render(fd, colors);

  int lfd = open(filename, O_RDONLY);
  char buffer[100];
  int len = read(lfd, buffer, sizeof(buffer));
  if (len == -1) {
    ASSERT_EQ(errno, 0);
  }
  buffer[len] = 0;
  close(lfd);

  ASSERT_EQ(strstr(buffer, "\x1b[1;33;44m"), buffer);
  GTEST_COUT << "buffer:" << buffer << std::endl;

  ASSERT_EQ(len, 29);
  ASSERT_STREQ(buffer, "\x1b[1;33;44mM \bE \bO \bW \b! \b\x1b[0m");
}

} // namespace