/*
 * 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);
    }
}
