/*
 *
 *    Copyright (c) 2011-2015 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    This document is the property of Nest. It is considered
 *    confidential and proprietary information.
 *
 *    This document may not be reproduced or transmitted in any form,
 *    in whole or in part, without the express written permission of
 *    Nest.
 *
 *    Description:
 *        Simplified implementation of OpenSSL's error handling functions
 *        that avoids dynamic memory allocation.
 */

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

#include <openssl/err.h>

static unsigned long sErrorStack[ERR_NUM_ERRORS];
size_t sTop = 0;
size_t sBottom = 0;

unsigned long ERR_get_error(void)
{
    if (sTop == sBottom)
        return 0;

    unsigned long err = sErrorStack[sBottom++];
    if (sBottom == ERR_NUM_ERRORS)
        sBottom = 0;

    return err;
}

unsigned long ERR_peek_error(void)
{
    if (sTop == sBottom)
        return 0;
    return sErrorStack[sBottom];
}

unsigned long ERR_peek_last_error(void)
{
    if (sTop == sBottom)
        return 0;
    size_t last = (sTop != 0) ? sTop - 1 : ERR_NUM_ERRORS - 1;
    return sErrorStack[last];
}

void ERR_put_error(int lib, int func, int reason, const char *file, int line)
{
    sErrorStack[sTop++] = ERR_PACK(lib, func, reason);
    if (sTop == ERR_NUM_ERRORS)
        sTop = 0;
    if (sTop == sBottom)
    {
        sBottom++;
        if (sBottom == ERR_NUM_ERRORS)
            sBottom = 0;
    }
}

void ERR_clear_error(void)
{
    sTop = sBottom = 0;
}

void ERR_print_errors_fp(FILE *fp)
{
    unsigned long err;

    while ((err = ERR_get_error()) != 0)
    {
        fprintf(fp, "Error %08lX (lib %d, func %d, reason %d)\n", err, ERR_GET_LIB(err), ERR_GET_FUNC(err),
                ERR_GET_REASON(err));
    }
}
