/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include "config.h"

#include "error.h"

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

#ifdef HAVE_LIBPTHREAD
#include <pthread.h>
#endif

/*
 * Error strings
 */

const char* __GUAC_STATUS_SUCCESS_STR           = "Success";
const char* __GUAC_STATUS_NO_MEMORY_STR         = "Insufficient memory";
const char* __GUAC_STATUS_CLOSED_STR            = "Closed";
const char* __GUAC_STATUS_TIMEOUT_STR           = "Timed out";
const char* __GUAC_STATUS_IO_ERROR_STR          = "Input/output error";
const char* __GUAC_STATUS_INVALID_ARGUMENT_STR  = "Invalid argument";
const char* __GUAC_STATUS_INTERNAL_ERROR_STR    = "Internal error";
const char* __GUAC_STATUS_UNKNOWN_STATUS_STR    = "UNKNOWN STATUS CODE";
const char* __GUAC_STATUS_NO_SPACE_STR          = "Insufficient space";
const char* __GUAC_STATUS_INPUT_TOO_LARGE_STR   = "Input too large";
const char* __GUAC_STATUS_RESULT_TOO_LARGE_STR  = "Result too large";
const char* __GUAC_STATUS_PERMISSION_DENIED_STR = "Permission denied";
const char* __GUAC_STATUS_BUSY_STR              = "Resource busy";
const char* __GUAC_STATUS_NOT_AVAILABLE_STR     = "Resource not available";
const char* __GUAC_STATUS_NOT_SUPPORTED_STR     = "Not supported";
const char* __GUAC_STATUS_NOT_INPLEMENTED_STR   = "Not implemented";
const char* __GUAC_STATUS_TRY_AGAIN_STR         = "Temporary failure";
const char* __GUAC_STATUS_PROTOCOL_ERROR_STR    = "Protocol violation";
const char* __GUAC_STATUS_NOT_FOUND_STR         = "Not found";
const char* __GUAC_STATUS_CANCELED_STR          = "Canceled";
const char* __GUAC_STATUS_OUT_OF_RANGE_STR      = "Value out of range";
const char* __GUAC_STATUS_REFUSED_STR           = "Operation refused";
const char* __GUAC_STATUS_TOO_MANY_STR          = "Insufficient resources";
const char* __GUAC_STATUS_WOULD_BLOCK_STR       = "Operation would block";

const char* guac_status_string(guac_status status) {

    switch (status) {

        /* No error */
		case GUAC_STATUS_SUCCESS:
            return __GUAC_STATUS_SUCCESS_STR;

        /* Out of memory */
		case GUAC_STATUS_NO_MEMORY:
            return __GUAC_STATUS_NO_MEMORY_STR;

        /* End of stream */
		case GUAC_STATUS_CLOSED:
            return __GUAC_STATUS_CLOSED_STR;

        /* Timeout */
		case GUAC_STATUS_TIMEOUT:
            return __GUAC_STATUS_TIMEOUT_STR;

        /* Further information in errno */
		case GUAC_STATUS_SEE_ERRNO:
            return strerror(errno);

        /* Input/output error */
		case GUAC_STATUS_IO_ERROR:
            return __GUAC_STATUS_IO_ERROR_STR;

        /* Invalid argument */
		case GUAC_STATUS_INVALID_ARGUMENT:
            return __GUAC_STATUS_INVALID_ARGUMENT_STR;

        /* Internal error */
		case GUAC_STATUS_INTERNAL_ERROR:
            return __GUAC_STATUS_INTERNAL_ERROR_STR;

        /* Out of space */
		case GUAC_STATUS_NO_SPACE:
            return __GUAC_STATUS_NO_SPACE_STR;

        /* Input too large */
        case GUAC_STATUS_INPUT_TOO_LARGE:
            return __GUAC_STATUS_INPUT_TOO_LARGE_STR;

        /* Result too large */
        case GUAC_STATUS_RESULT_TOO_LARGE:
            return __GUAC_STATUS_RESULT_TOO_LARGE_STR;

        /* Permission denied */
        case GUAC_STATUS_PERMISSION_DENIED:
            return __GUAC_STATUS_PERMISSION_DENIED_STR;

        /* Resource is busy */
        case GUAC_STATUS_BUSY:
            return __GUAC_STATUS_BUSY_STR;

        /* Resource not available */
        case GUAC_STATUS_NOT_AVAILABLE:
            return __GUAC_STATUS_NOT_AVAILABLE_STR;

        /* Not supported */
        case GUAC_STATUS_NOT_SUPPORTED:
            return __GUAC_STATUS_NOT_SUPPORTED_STR;

        /* Not implemented */
        case GUAC_STATUS_NOT_INPLEMENTED:
            return __GUAC_STATUS_NOT_INPLEMENTED_STR;

        /* Temporary failure */
        case GUAC_STATUS_TRY_AGAIN:
            return __GUAC_STATUS_TRY_AGAIN_STR;

        /* Guacamole protocol error */
        case GUAC_STATUS_PROTOCOL_ERROR:
            return __GUAC_STATUS_PROTOCOL_ERROR_STR;

        /* Resource not found */
        case GUAC_STATUS_NOT_FOUND:
            return __GUAC_STATUS_NOT_FOUND_STR;

        /* Operation canceled */
        case GUAC_STATUS_CANCELED:
            return __GUAC_STATUS_CANCELED_STR;

        /* Value out of range */
        case GUAC_STATUS_OUT_OF_RANGE:
            return __GUAC_STATUS_OUT_OF_RANGE_STR;

        /* Operation refused */
        case GUAC_STATUS_REFUSED:
            return __GUAC_STATUS_REFUSED_STR;

        /* Too many resource in use */
        case GUAC_STATUS_TOO_MANY:
            return __GUAC_STATUS_TOO_MANY_STR;

        /* Operation would block */
        case GUAC_STATUS_WOULD_BLOCK:
            return __GUAC_STATUS_WOULD_BLOCK_STR;

        /* Unknown status code */
        default:
            return __GUAC_STATUS_UNKNOWN_STATUS_STR;

    }

}

#ifdef HAVE_LIBPTHREAD

/* PThread implementation of __guac_error */

static pthread_key_t  __guac_error_key;
static pthread_once_t __guac_error_key_init = PTHREAD_ONCE_INIT;

static pthread_key_t  __guac_error_message_key;
static pthread_once_t __guac_error_message_key_init = PTHREAD_ONCE_INIT;

static void __guac_free_pointer(void* pointer) {

    /* Free memory allocated to status variable */
    free(pointer);

}

static void __guac_alloc_error_key() {

    /* Create key, destroy any allocated variable on thread exit */
    pthread_key_create(&__guac_error_key, __guac_free_pointer);

}

static void __guac_alloc_error_message_key() {

    /* Create key, destroy any allocated variable on thread exit */
    pthread_key_create(&__guac_error_message_key, __guac_free_pointer);

}

guac_status* __guac_error() {

    /* Pointer for thread-local data */
    guac_status* status;

    /* Init error key, if not already initialized */
    pthread_once(&__guac_error_key_init, __guac_alloc_error_key);

    /* Retrieve thread-local status variable */
    status = (guac_status*) pthread_getspecific(__guac_error_key);

    /* Allocate thread-local status variable if not already allocated */
    if (status == NULL) {
        status = malloc(sizeof(guac_status));
        pthread_setspecific(__guac_error_key, status);
    }

    return status;

}

const char** __guac_error_message() {

    /* Pointer for thread-local data */
    const char** message;

    /* Init error message key, if not already initialized */
    pthread_once(
        &__guac_error_message_key_init,
        __guac_alloc_error_message_key
    );

    /* Retrieve thread-local message variable */
    message = (const char**) pthread_getspecific(__guac_error_message_key);

    /* Allocate thread-local message variable if not already allocated */
    if (message == NULL) {
        message = malloc(sizeof(const char*));
        pthread_setspecific(__guac_error_message_key, message);
    }

    return message;

}

#else

/* Default (not-threadsafe) implementation */
static guac_status __guac_error_unsafe_storage;
static const char** __guac_error_message_unsafe_storage;

guac_status* __guac_error() {
    return &__guac_error_unsafe_storage;
}

const char** __guac_error_message() {
    return &__guac_error_message_unsafe_storage;
}

/* Warn about threadsafety */
#warn No threadsafe implementation of __guac_error exists for your platform, so a default non-threadsafe implementation has been used instead. This may lead to incorrect status codes being reported for failures. Please consider adding support for your platform, or filing a bug report with the Guacamole project.

#endif

