/* 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

#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 len = 1 + (rand() % 3);
  char *ret = malloc(len + 1);
  unsigned i;

  for (i = 0; i < len; i++) {
    ret[i] = '0' + (rand() & 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 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() % 3;
    switch (action) {
      case 0:
        s = rand_string();
        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();
        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();
        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;
}
