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

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

#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/mem.h>


static bool TestOverflow() {
  for (unsigned i = 0; i < ERR_NUM_ERRORS*2; i++) {
    ERR_put_error(1, 2, i+1, "test", 1);
  }

  for (unsigned i = 0; i < ERR_NUM_ERRORS - 1; i++) {
    uint32_t err = ERR_get_error();
    /* Errors are returned in order they were pushed, with the least recent ones
     * removed, up to |ERR_NUM_ERRORS - 1| errors. So the errors returned are
     * |ERR_NUM_ERRORS + 2| through |ERR_NUM_ERRORS * 2|, inclusive. */
    if (err == 0 || ERR_GET_REASON(err) != i + ERR_NUM_ERRORS + 2) {
      fprintf(stderr, "ERR_get_error failed at %u\n", i);
      return false;
    }
  }

  if (ERR_get_error() != 0) {
    fprintf(stderr, "ERR_get_error more than the expected number of values.\n");
    return false;
  }

  return true;
}

static bool TestPutError() {
  if (ERR_get_error() != 0) {
    fprintf(stderr, "ERR_get_error returned value before an error was added.\n");
    return false;
  }

  ERR_put_error(1, 2, 3, "test", 4);
  ERR_add_error_data(1, "testing");

  int peeked_line, line, peeked_flags, flags;
  const char *peeked_file, *file, *peeked_data, *data;
  uint32_t peeked_packed_error =
      ERR_peek_error_line_data(&peeked_file, &peeked_line, &peeked_data,
                               &peeked_flags);
  uint32_t packed_error = ERR_get_error_line_data(&file, &line, &data, &flags);

  if (peeked_packed_error != packed_error ||
      peeked_file != file ||
      peeked_data != data ||
      peeked_flags != flags) {
    fprintf(stderr, "Bad peeked error data returned.\n");
    return false;
  }

  if (strcmp(file, "test") != 0 ||
      line != 4 ||
      (flags & ERR_FLAG_STRING) == 0 ||
      ERR_GET_LIB(packed_error) != 1 ||
      ERR_GET_FUNC(packed_error) != 2 ||
      ERR_GET_REASON(packed_error) != 3 ||
      strcmp(data, "testing") != 0) {
    fprintf(stderr, "Bad error data returned.\n");
    return false;
  }

  return true;
}

static bool TestClearError() {
  if (ERR_get_error() != 0) {
    fprintf(stderr, "ERR_get_error returned value before an error was added.\n");
    return false;
  }

  ERR_put_error(1, 2, 3, "test", 4);
  ERR_clear_error();

  if (ERR_get_error() != 0) {
    fprintf(stderr, "Error remained after clearing.\n");
    return false;
  }

  return true;
}

static bool TestPrint() {
  ERR_put_error(1, 2, 3, "test", 4);
  ERR_add_error_data(1, "testing");
  uint32_t packed_error = ERR_get_error();

  char buf[256];
  for (size_t i = 0; i <= sizeof(buf); i++) {
    ERR_error_string_n(packed_error, buf, i);
  }

  return true;
}

static bool TestRelease() {
  ERR_put_error(1, 2, 3, "test", 4);
  ERR_remove_thread_state(NULL);
  return true;
}

int main() {
  CRYPTO_library_init();

  if (!TestOverflow() ||
      !TestPutError() ||
      !TestClearError() ||
      !TestPrint() ||
      !TestRelease()) {
    return 1;
  }

  printf("PASS\n");
  return 0;
}
