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

#include <string.h>

#include "utils.h"
#include "gtest/gtest.h"

/*

int randint(int N);
int randrange(int M, int N);
char *repr(const char *data);
const char *strnstr(const char *source, int len, const char *needle);
int rstrnstr(const char *buffer, int len, const char *find);
int string_insert(char *buffer, int max_length, int pos, const char *insert);
void pcopy(char *pstring, char *str);

*/

namespace {

TEST(UtilsRandRange, rangehits_10k) {
  int x;
  int rmin = 5, rmax = 200;
  int max = -rmax, min = rmax * 2;

  for (x = 0; x < 10000; x++) {
    int r = randrange(rmin, rmax);
    if (r < min)
      min = r;
    if (r > max)
      max = r;
  }

  ASSERT_EQ(min, rmin);
  ASSERT_EQ(max, rmax);
}

TEST(UtilsRandInt, rangeint_10k) {
  int x;
  int rmax = 200;
  int max = -rmax, min = rmax * 2;

  for (x = 0; x < 10000; x++) {
    int r = randint(rmax);
    if (r < min)
      min = r;
    if (r > max)
      max = r;
  }

  ASSERT_EQ(min, 0);
  ASSERT_EQ(max, rmax - 1);
}

TEST(UtilsStrNStr, strnstr) {
  // const char *strnstr(const char *source, int len, const char *needle);
  char buffer[20];
  int size = sizeof(buffer);
  memset(buffer, ' ', size);
  ASSERT_EQ(strnstr(buffer, size, "?"), (char *)NULL);
  buffer[10] = '?';
  ASSERT_EQ(strnstr(buffer, size, "?"), &buffer[10]);
  ASSERT_EQ(strnstr(buffer, 10, "?"), (char *)NULL);
  buffer[11] = '!';
  ASSERT_EQ(strnstr(buffer, size, "?!"), &buffer[10]);
  ASSERT_EQ(strnstr(buffer, size, "??"), (char *)NULL);
  // Matches first char, but the length doesn't allow for a complete match.
  ASSERT_EQ(strnstr(buffer, 10, "?!"), (char *)NULL);
  // There, enough chars to find a match
  ASSERT_EQ(strnstr(buffer, 11, "?!"), &buffer[10]);
  buffer[2] = '?';
  buffer[5] = '?';
  buffer[1] = '!';
  // First char matches, but not complete
  ASSERT_EQ(strnstr(buffer, 10, "?!"), (char *)NULL);
  ASSERT_EQ(strnstr(buffer, 11, "?!"), &buffer[10]);
}

TEST(UtilsStringInsert, strin) {
  // int string_insert(char *buffer, int max_length, int pos, const char
  // *insert);
  char buffer[20];
  int size = sizeof(buffer);
  memset(buffer, 1, size);

  strcpy(buffer, "STARTEND");

  ASSERT_EQ(string_insert(buffer, size, 5, "XX"), 1);
  ASSERT_EQ(strncmp(buffer + 5, "XX", 2), 0);
  ASSERT_STREQ(buffer, "STARTXXEND");
  ASSERT_EQ(string_insert(buffer, size, 5, "ZZZ"), 1);
  ASSERT_STREQ(buffer, "STARTZZZXXEND");
  // 13 chars
  ASSERT_EQ(string_insert(buffer, size, 0, "12345"), 1);
  // 18 chars
  ASSERT_STREQ(buffer, "12345STARTZZZXXEND");
  ASSERT_EQ(string_insert(buffer, size, 5, "FAIL"), 0);
  ASSERT_EQ(string_insert(buffer, size, size, "!"), 0);
  ASSERT_EQ(string_insert(buffer, size, strlen(buffer), "!"), 1);
  ASSERT_STREQ(buffer, "12345STARTZZZXXEND!");
  // String is at max size.
  ASSERT_EQ(strlen(buffer), size - 1);
  // Can't insert base the end of the buffer
  ASSERT_EQ(string_insert(buffer, size, strlen(buffer), "!"), 0);
  ASSERT_STREQ(buffer, "12345STARTZZZXXEND!");
}

} // namespace