/* 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 _POSIX_SOURCE
#define _BSD_SOURCE

#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;
}
