/* Copyright (c) 2014, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#define _BSD_SOURCE

#if !defined(__APPLE__)
/* _POSIX_SOURCE is needed on Linux in order to get rand_r, but on OS X causes
 * a build failure. */
#define _POSIX_SOURCE
#endif

#include <openssl/lhash.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct dummy_lhash_node {
  char *s;
  struct dummy_lhash_node *next;
};

struct dummy_lhash {
  struct dummy_lhash_node *head;
};

static void dummy_lh_free(struct dummy_lhash *lh) {
  struct dummy_lhash_node *cur, *next;

  for (cur = lh->head; cur != NULL; cur = next) {
    next = cur->next;
    free(cur->s);
    free(cur);
  }
}

static size_t dummy_lh_num_items(const struct dummy_lhash *lh) {
  size_t count = 0;
  struct dummy_lhash_node *cur;

  for (cur = lh->head; cur != NULL; cur = cur->next) {
    count++;
  }

  return count;
}

static char *dummy_lh_retrieve(struct dummy_lhash *lh, const char *s) {
  struct dummy_lhash_node *cur;

  for (cur = lh->head; cur != NULL; cur = cur->next) {
    if (strcmp(cur->s, s) == 0) {
      return cur->s;
    }
  }

  return NULL;
}

static int dummy_lh_insert(struct dummy_lhash *lh, char **old_data, char *s) {
  struct dummy_lhash_node *node, *cur;

  for (cur = lh->head; cur != NULL; cur = cur->next) {
    if (strcmp(cur->s, s) == 0) {
      *old_data = cur->s;
      cur->s = s;
      return 1;
    }
  }

  node = malloc(sizeof(struct dummy_lhash_node));
  *old_data = NULL;
  node->s = s;
  node->next = lh->head;
  lh->head = node;
  return 1;
}

static char *dummy_lh_delete(struct dummy_lhash *lh, const void *s) {
  struct dummy_lhash_node *cur, **next_ptr;
  char *ret;

  next_ptr = &lh->head;
  for (cur = lh->head; cur != NULL; cur = cur->next) {
    if (strcmp(cur->s, s) == 0) {
      ret = cur->s;
      *next_ptr = cur->next;
      free(cur);
      return ret;
    }
    next_ptr = &cur->next;
  }

  return NULL;
}

static char *rand_string(unsigned *rand_state) {
  unsigned len = 1 + (rand_r(rand_state) % 3);
  char *ret = malloc(len + 1);
  unsigned i;

  for (i = 0; i < len; i++) {
    ret[i] = '0' + (rand_r(rand_state) & 7);
  }
  ret[i] = 0;

  return ret;
}

int main(int argc, char **argv) {
  _LHASH *lh = lh_new(NULL, NULL);
  struct dummy_lhash dummy_lh = {NULL};
  unsigned rand_state = 0;
  unsigned i;

  for (i = 0; i < 100000; i++) {
    unsigned action;
    char *s, *s1, *s2;

    if (dummy_lh_num_items(&dummy_lh) != lh_num_items(lh)) {
      fprintf(stderr, "Length mismatch\n");
      return 1;
    }

    action = rand_r(&rand_state) % 3;
    switch (action) {
      case 0:
        s = rand_string(&rand_state);
        s1 = (char *)lh_retrieve(lh, s);
        s2 = dummy_lh_retrieve(&dummy_lh, s);
        if (s1 != NULL && (s2 == NULL || strcmp(s1, s2) != 0)) {
          fprintf(stderr, "lh_retrieve failure\n");
          abort();
        }
        free(s);
        break;

      case 1:
        s = rand_string(&rand_state);
        lh_insert(lh, (void **)&s1, s);
        dummy_lh_insert(&dummy_lh, &s2, strdup(s));

        if (s1 != NULL && (s2 == NULL || strcmp(s1, s2) != 0)) {
          fprintf(stderr, "lh_insert failure\n");
          abort();
        }

        if (s1) {
          free(s1);
        }
        if (s2) {
          free(s2);
        }
        break;

      case 2:
        s = rand_string(&rand_state);
        s1 = lh_delete(lh, s);
        s2 = dummy_lh_delete(&dummy_lh, s);

        if (s1 != NULL && (s2 == NULL || strcmp(s1, s2) != 0)) {
          fprintf(stderr, "lh_insert failure\n");
          abort();
        }

        if (s1) {
          free(s1);
        }
        if (s2) {
          free(s2);
        }
        free(s);
        break;

      default:
        abort();
    }
  }

  lh_doall(lh, free);
  lh_free(lh);
  dummy_lh_free(&dummy_lh);
  printf("PASS\n");
  return 0;
}
