/*
 * Copyright (c) 2006-Present, Redis Ltd.
 * All rights reserved.
 *
 * Licensed under your choice of the Redis Source Available License 2.0
 * (RSALv2); or (b) the Server Side Public License v1 (SSPLv1); or (c) the
 * GNU Affero General Public License v3 (AGPLv3).
*/
#include "test_util.h"
#include <rmalloc.h>
#include <stopwords.h>
#include <rmutil/args.h>

void RMUTil_InitAlloc();

int testStopwordList() {

  char *terms[] = {strdup("foo"), strdup("bar"), strdup("שלום"), strdup("Hello"), strdup("WORLD")};
  const char *test_terms[] = {"foo", "bar", "שלום", "hello", "world"};

  StopWordList *sl = NewStopWordListCStr((const char **)terms, sizeof(terms) / sizeof(char *));
  ASSERT(sl != NULL);

  for (int i = 0; i < sizeof(test_terms) / sizeof(const char *); i++) {
    ASSERT(StopWordList_Contains(sl, test_terms[i], strlen(test_terms[i])));
  }

  ASSERT(!StopWordList_Contains(sl, "asdfasdf", strlen("asdfasdf")));
  ASSERT(!StopWordList_Contains(sl, NULL, 0));
  ASSERT(!StopWordList_Contains(NULL, NULL, 0));

  StopWordList_Free(sl);
  for (int i = 0; i < sizeof(terms) / sizeof(const char *); i++) {
    free(terms[i]);
  }
  return 0;
}

int testDefaultStopwords() {

  StopWordList *sl = DefaultStopWordList();
  for (int i = 0; DEFAULT_STOPWORDS[i] != NULL; i++) {
    ASSERT(StopWordList_Contains(sl, DEFAULT_STOPWORDS[i], strlen(DEFAULT_STOPWORDS[i])));
  }
  const char *test_terms[] = {"foo", "bar", "שלום", "hello", "world", "x", "i", "t"};
  for (int i = 0; i < sizeof(test_terms) / sizeof(const char *); i++) {
    // printf("checking %s\n", test_terms[i]);
    ASSERT(!StopWordList_Contains(sl, test_terms[i], strlen(test_terms[i])));
  }

  StopWordList_Free(sl);
  return 0;
}

int testStopwordListAC() {

  // Same inputs as testStopwordList, but consumed via an ArgsCursor.
  const char *terms[] = {"foo", "bar", "שלום", "Hello", "WORLD"};
  const char *test_terms[] = {"foo", "bar", "שלום", "hello", "world"};
  const size_t nterms = sizeof(terms) / sizeof(const char *);

  ArgsCursor ac;
  ArgsCursor_InitCString(&ac, terms, nterms);

  StopWordList *sl = NewStopWordListAC(&ac);
  ASSERT(sl != NULL);
  // The cursor should have been fully consumed.
  ASSERT_EQUAL(0, AC_NumRemaining(&ac));

  for (int i = 0; i < sizeof(test_terms) / sizeof(const char *); i++) {
    ASSERT(StopWordList_Contains(sl, test_terms[i], strlen(test_terms[i])));
  }

  ASSERT(!StopWordList_Contains(sl, "asdfasdf", strlen("asdfasdf")));
  StopWordList_Free(sl);
  return 0;
}

int testStopwordListACEmpty() {

  // An empty cursor should produce a non-NULL (cached, empty) list.
  ArgsCursor ac;
  ArgsCursor_InitCString(&ac, NULL, 0);

  StopWordList *sl = NewStopWordListAC(&ac);
  ASSERT(sl != NULL);
  ASSERT(!StopWordList_Contains(sl, "foo", 3));
  StopWordList_Free(sl);
  return 0;
}

TEST_MAIN({
  RMUTil_InitAlloc();
  TESTFUNC(testStopwordList);
  TESTFUNC(testStopwordListAC);
  TESTFUNC(testStopwordListACEmpty);
  TESTFUNC(testDefaultStopwords);
  StopWordList_FreeGlobals();
});
