
/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkTLS.h"
#include "SkTypes.h"
#include "SkError.h"
#include "SkErrorInternals.h"

#include <stdio.h>
#include <stdarg.h>

namespace {
void *CreateThreadError() { return new SkError(kNoError_SkError); }
void DeleteThreadError(void *v) { delete reinterpret_cast<SkError *>(v); }
    #define THREAD_ERROR \
        (*reinterpret_cast<SkError*>(SkTLS::Get(CreateThreadError, DeleteThreadError)))

    void *CreateThreadErrorCallback() {
        return new SkErrorCallbackFunction(SkErrorInternals::DefaultErrorCallback);
    }
    void DeleteThreadErrorCallback(void* v) {
        delete reinterpret_cast<SkErrorCallbackFunction *>(v);
    }

    #define THREAD_ERROR_CALLBACK                                                             \
        *(reinterpret_cast<SkErrorCallbackFunction *>(SkTLS::Get(CreateThreadErrorCallback,   \
                                                                 DeleteThreadErrorCallback)))

    void *CreateThreadErrorContext() { return new void **(nullptr); }
    void DeleteThreadErrorContext(void *v) { delete reinterpret_cast<void **>(v); }
    #define THREAD_ERROR_CONTEXT \
        (*reinterpret_cast<void **>(SkTLS::Get(CreateThreadErrorContext, DeleteThreadErrorContext)))

    #define ERROR_STRING_LENGTH 2048

    void *CreateThreadErrorString() { return new char[(ERROR_STRING_LENGTH)]; }
    void DeleteThreadErrorString(void *v) { delete[] reinterpret_cast<char *>(v); }
    #define THREAD_ERROR_STRING \
        (reinterpret_cast<char *>(SkTLS::Get(CreateThreadErrorString, DeleteThreadErrorString)))
}

SkError SkGetLastError() {
    return SkErrorInternals::GetLastError();
}
void SkClearLastError() {
    SkErrorInternals::ClearError();
}
void SkSetErrorCallback(SkErrorCallbackFunction cb, void *context) {
    SkErrorInternals::SetErrorCallback(cb, context);
}
const char *SkGetLastErrorString() {
    return SkErrorInternals::GetLastErrorString();
}

// ------------ Private Error functions ---------

void SkErrorInternals::SetErrorCallback(SkErrorCallbackFunction cb, void *context) {
    if (cb == nullptr) {
        THREAD_ERROR_CALLBACK = SkErrorInternals::DefaultErrorCallback;
    } else {
        THREAD_ERROR_CALLBACK = cb;
    }
    THREAD_ERROR_CONTEXT = context;
}

void SkErrorInternals::DefaultErrorCallback(SkError code, void *context) {
    SkDebugf("Skia Error: %s\n", SkGetLastErrorString());
}

void SkErrorInternals::ClearError() {
    SkErrorInternals::SetError( kNoError_SkError, "All is well" );
}

SkError SkErrorInternals::GetLastError() {
    return THREAD_ERROR;
}

const char *SkErrorInternals::GetLastErrorString() {
    return THREAD_ERROR_STRING;
}

void SkErrorInternals::SetError(SkError code, const char *fmt, ...) {
    THREAD_ERROR = code;
    va_list args;

    char *str = THREAD_ERROR_STRING;
    const char *error_name = nullptr;
    switch( code ) {
        case kNoError_SkError:
            error_name = "No Error";
            break;
        case kInvalidArgument_SkError:
            error_name = "Invalid Argument";
            break;
        case kInvalidOperation_SkError:
            error_name = "Invalid Operation";
            break;
        case kInvalidHandle_SkError:
            error_name = "Invalid Handle";
            break;
        case kInvalidPaint_SkError:
            error_name = "Invalid Paint";
            break;
        case kOutOfMemory_SkError:
            error_name = "Out Of Memory";
            break;
        case kParseError_SkError:
            error_name = "Parse Error";
            break;
        default:
            error_name = "Unknown error";
            break;
    }

    sprintf( str, "%s: ", error_name );
    int string_left = SkToInt(ERROR_STRING_LENGTH - strlen(str));
    str += strlen(str);

    va_start( args, fmt );
    vsnprintf( str, string_left, fmt, args );
    va_end( args );
    SkErrorCallbackFunction fn = THREAD_ERROR_CALLBACK;
    if (fn && code != kNoError_SkError) {
        fn(code, THREAD_ERROR_CONTEXT);
    }
}
