/*-------------------------------------------------------------------------
 * drawElements Quality Program Helper Library
 * -------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed 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.
 *
 *//*!
 * \file
 * \brief System handler handler override
 *//*--------------------------------------------------------------------*/

#include "qpCrashHandler.h"
#include "qpDebugOut.h"

#include "deThread.h"
#include "deMemory.h"
#include "deString.h"
#include "deMutex.h"

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

#if (DE_OS == DE_OS_UNIX)
#include <unistd.h>
#include <execinfo.h>
#include <errno.h>
#include <inttypes.h>
#endif

#if 0
#define DBGPRINT(X) qpPrintf X
#else
#define DBGPRINT(X)
#endif

/* Crash info write helper. */
static void writeInfoFormat(qpWriteCrashInfoFunc writeFunc, void *userPtr, const char *format, ...)
{
    char buf[256];
    va_list ap;

    va_start(ap, format);
    vsnprintf(buf, sizeof(buf), format, ap);
    va_end(ap);

    writeFunc(userPtr, buf);
}

/* Shared crash info. */
typedef enum qpCrashType_e
{
    QP_CRASHTYPE_SEGMENTATION_FAULT = 0,
    QP_CRASHTYPE_ASSERT,
    QP_CRASHTYPE_UNHANDLED_EXCEPTION,
    QP_CRASHTYPE_OTHER,

    QP_CRASHTYPE_LAST
} qpCrashType;

typedef struct qpCrashInfo_s
{
    qpCrashType type;
    const char *message;
    const char *file;
    int line;
} qpCrashInfo;

static void qpCrashInfo_init(qpCrashInfo *info)
{
    info->type    = QP_CRASHTYPE_LAST;
    info->message = DE_NULL;
    info->file    = DE_NULL;
    info->line    = 0;
}

static void qpCrashInfo_set(qpCrashInfo *info, qpCrashType type, const char *message, const char *file, int line)
{
    info->type    = type;
    info->message = message;
    info->file    = file;
    info->line    = line;
}

static void qpCrashInfo_write(qpCrashInfo *info, qpWriteCrashInfoFunc writeInfo, void *userPtr)
{
    switch (info->type)
    {
    case QP_CRASHTYPE_SEGMENTATION_FAULT:
        writeInfoFormat(writeInfo, userPtr, "Segmentation fault: '%s'\n", info->message);
        break;

    case QP_CRASHTYPE_UNHANDLED_EXCEPTION:
        writeInfoFormat(writeInfo, userPtr, "Unhandled exception: '%s'\n", info->message);
        break;

    case QP_CRASHTYPE_ASSERT:
        writeInfoFormat(writeInfo, userPtr, "Assertion '%s' failed at %s:%d\n", info->message, info->file, info->line);
        break;

    case QP_CRASHTYPE_OTHER:
    default:
        writeInfoFormat(writeInfo, userPtr, "Crash: '%s'\n", info->message);
        break;
    }
}

static void defaultWriteInfo(void *userPtr, const char *infoString)
{
    DE_UNREF(userPtr);
    qpPrintf("%s", infoString);
}

static void defaultCrashHandler(qpCrashHandler *crashHandler, void *userPtr)
{
    DE_UNREF(userPtr);
    qpCrashHandler_writeCrashInfo(crashHandler, defaultWriteInfo, DE_NULL);
    qpDief("Test process crashed");
}

#if (DE_OS == DE_OS_WIN32) && (DE_COMPILER == DE_COMPILER_MSC)

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

/* DbgHelp.h generates C4091 */
#pragma warning(push)
#pragma warning(disable : 4091)
#include <DbgHelp.h>
#pragma warning(pop)

struct qpCrashHandler_s
{
    qpCrashHandlerFunc crashHandlerFunc;
    void *handlerUserPointer;

    deMutex crashHandlerLock;
    qpCrashInfo crashInfo;
    uintptr_t crashAddress;

    LPTOP_LEVEL_EXCEPTION_FILTER oldExceptionFilter;
};

qpCrashHandler *g_crashHandler = DE_NULL;

static LONG WINAPI unhandledExceptionFilter(struct _EXCEPTION_POINTERS *info)
{
    qpCrashType crashType = QP_CRASHTYPE_LAST;
    const char *reason    = DE_NULL;

    /* Skip breakpoints. */
    if (info->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT)
    {
        DBGPRINT(("qpCrashHandler::unhandledExceptionFilter(): breakpoint\n"));
        return EXCEPTION_CONTINUE_SEARCH;
    }

    /* If no handler present (how could that be?), don't handle. */
    if (g_crashHandler == DE_NULL)
    {
        DBGPRINT(("qpCrashHandler::unhandledExceptionFilter(): no crash handler registered\n"));
        return EXCEPTION_CONTINUE_SEARCH;
    }

    /* If we have a debugger, let it handle the exception. */
    if (IsDebuggerPresent())
    {
        DBGPRINT(("qpCrashHandler::unhandledExceptionFilter(): debugger present\n"));
        return EXCEPTION_CONTINUE_SEARCH;
    }

    /* Acquire crash handler lock. Otherwise we might get strange behavior when multiple threads enter crash handler simultaneously. */
    deMutex_lock(g_crashHandler->crashHandlerLock);

    /* Map crash type. */
    switch (info->ExceptionRecord->ExceptionCode)
    {
    case EXCEPTION_ACCESS_VIOLATION:
        crashType = QP_CRASHTYPE_SEGMENTATION_FAULT;
        reason    = "Access violation";
        break;

    case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
        crashType = QP_CRASHTYPE_SEGMENTATION_FAULT;
        reason    = "Array bounds exceeded";
        break;

    case EXCEPTION_ILLEGAL_INSTRUCTION:
        crashType = QP_CRASHTYPE_OTHER;
        reason    = "Illegal instruction";
        break;

    case EXCEPTION_STACK_OVERFLOW:
        crashType = QP_CRASHTYPE_OTHER;
        reason    = "Stack overflow";
        break;

    default:
        /* \todo [pyry] Others. */
        crashType = QP_CRASHTYPE_OTHER;
        reason    = "";
        break;
    }

    /* Store reason. */
    qpCrashInfo_set(&g_crashHandler->crashInfo, crashType, reason, __FILE__, __LINE__);

    /* Store win32-specific crash info. */
    g_crashHandler->crashAddress = (uintptr_t)info->ExceptionRecord->ExceptionAddress;

    /* Handle the crash. */
    DBGPRINT(("qpCrashHandler::unhandledExceptionFilter(): handled quietly\n"));
    if (g_crashHandler->crashHandlerFunc != DE_NULL)
        g_crashHandler->crashHandlerFunc(g_crashHandler, g_crashHandler->handlerUserPointer);

    /* Release lock. */
    deMutex_unlock(g_crashHandler->crashHandlerLock);

    return EXCEPTION_EXECUTE_HANDLER;
}

static void assertFailureCallback(const char *expr, const char *file, int line)
{
    /* Don't execute crash handler function if debugger is present. */
    if (IsDebuggerPresent())
    {
        DBGPRINT(("qpCrashHandler::assertFailureCallback(): debugger present\n"));
        return;
    }

    /* Acquire crash handler lock. */
    deMutex_lock(g_crashHandler->crashHandlerLock);

    /* Store info. */
    qpCrashInfo_set(&g_crashHandler->crashInfo, QP_CRASHTYPE_ASSERT, expr, file, line);
    g_crashHandler->crashAddress = 0;

    /* Handle the crash. */
    if (g_crashHandler->crashHandlerFunc != DE_NULL)
        g_crashHandler->crashHandlerFunc(g_crashHandler, g_crashHandler->handlerUserPointer);

    /* Release lock. */
    deMutex_unlock(g_crashHandler->crashHandlerLock);
}

qpCrashHandler *qpCrashHandler_create(qpCrashHandlerFunc handlerFunc, void *userPointer)
{
    /* Allocate & initialize. */
    qpCrashHandler *handler = (qpCrashHandler *)deCalloc(sizeof(qpCrashHandler));
    DBGPRINT(("qpCrashHandler::create() -- Win32\n"));
    if (!handler)
        return handler;

    DE_ASSERT(g_crashHandler == DE_NULL);

    handler->crashHandlerFunc   = handlerFunc ? handlerFunc : defaultCrashHandler;
    handler->handlerUserPointer = userPointer;

    /* Create lock for crash handler. \note Has to be recursive or otherwise crash in assert failure causes deadlock. */
    {
        deMutexAttributes attr;
        attr.flags                = DE_MUTEX_RECURSIVE;
        handler->crashHandlerLock = deMutex_create(&attr);

        if (!handler->crashHandlerLock)
        {
            deFree(handler);
            return DE_NULL;
        }
    }

    qpCrashInfo_init(&handler->crashInfo);
    handler->crashAddress = 0;

    /* Unhandled exception filter. */
    handler->oldExceptionFilter = SetUnhandledExceptionFilter(unhandledExceptionFilter);

    /* Prevent nasty error dialog. */
    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);

    /* DE_ASSERT callback. */
    deSetAssertFailureCallback(assertFailureCallback);

    g_crashHandler = handler;
    return handler;
}

void qpCrashHandler_destroy(qpCrashHandler *handler)
{
    DBGPRINT(("qpCrashHandler::destroy()\n"));

    DE_ASSERT(g_crashHandler == handler);

    deSetAssertFailureCallback(DE_NULL);
    SetUnhandledExceptionFilter(handler->oldExceptionFilter);

    g_crashHandler = DE_NULL;
    deFree(handler);
}

enum
{
    MAX_NAME_LENGTH = 64
};

void qpCrashHandler_writeCrashInfo(qpCrashHandler *handler, qpWriteCrashInfoFunc writeInfo, void *userPtr)
{
    void *addresses[32];
    HANDLE process;

    /* Symbol info struct. */
    uint8_t symInfoStorage[sizeof(SYMBOL_INFO) + MAX_NAME_LENGTH];
    SYMBOL_INFO *symInfo = (SYMBOL_INFO *)symInfoStorage;

    DE_STATIC_ASSERT(sizeof(TCHAR) == sizeof(uint8_t));

    /* Write basic info. */
    qpCrashInfo_write(&handler->crashInfo, writeInfo, userPtr);

    /* Acquire process handle and initialize symbols. */
    process = GetCurrentProcess();

    /* Write backtrace. */
    if (SymInitialize(process, NULL, TRUE))
    {
        int batchStart     = 0;
        int globalFrameNdx = 0;

        /* Initialize symInfo. */
        deMemset(symInfo, 0, sizeof(symInfoStorage));
        symInfo->SizeOfStruct = sizeof(SYMBOL_INFO);
        symInfo->MaxNameLen   = MAX_NAME_LENGTH;

        /* Print address and symbol where crash happened. */
        if (handler->crashAddress != 0)
        {
            BOOL symInfoOk = SymFromAddr(process, (DWORD64)handler->crashAddress, 0, symInfo);

            writeInfoFormat(writeInfo, userPtr, "  at %p %s%s\n", handler->crashAddress,
                            symInfoOk ? symInfo->Name : "(unknown)", symInfoOk ? "()" : "");
        }

        writeInfo(userPtr, "Backtrace:\n");

        for (;;)
        {
            int curFrame;
            int numInBatch;

            /* Get one batch. */
            numInBatch = CaptureStackBackTrace(batchStart, DE_LENGTH_OF_ARRAY(addresses), addresses, NULL);

            for (curFrame = 0; curFrame < numInBatch; curFrame++)
            {
                BOOL symInfoOk = SymFromAddr(process, (DWORD64)addresses[curFrame], 0, symInfo);

                writeInfoFormat(writeInfo, userPtr, "  %2d: %p %s%s\n", globalFrameNdx++, addresses[curFrame],
                                symInfoOk ? symInfo->Name : "(unknown)", symInfoOk ? "()" : "");
            }

            batchStart += numInBatch;

            /* Check if we hit end of stack trace. */
            if (numInBatch == 0 || numInBatch < DE_LENGTH_OF_ARRAY(addresses))
                break;
        }
    }
}

#else /* posix / generic implementation */

#if defined(QP_USE_SIGNAL_HANDLER)
#include <signal.h>
#endif

#if defined(QP_USE_SIGNAL_HANDLER)

typedef struct SignalInfo_s
{
    int signalNum;
    qpCrashType type;
    const char *name;
} SignalInfo;

static const SignalInfo s_signals[] = {
    {SIGABRT, QP_CRASHTYPE_UNHANDLED_EXCEPTION, "SIGABRT"}, {SIGILL, QP_CRASHTYPE_OTHER, "SIGILL"},
    {SIGSEGV, QP_CRASHTYPE_SEGMENTATION_FAULT, "SIGSEGV"},  {SIGFPE, QP_CRASHTYPE_OTHER, "SIGFPE"},
    {SIGBUS, QP_CRASHTYPE_SEGMENTATION_FAULT, "SIGBUS"},    {SIGPIPE, QP_CRASHTYPE_OTHER, "SIGPIPE"}};

#endif /* QP_USE_SIGNAL_HANDLER */

struct qpCrashHandler_s
{
    qpCrashHandlerFunc crashHandlerFunc;
    void *handlerUserPointer;

    qpCrashInfo crashInfo;
    int crashSignal;

#if defined(QP_USE_SIGNAL_HANDLER)
    struct sigaction oldHandlers[DE_LENGTH_OF_ARRAY(s_signals)];
#endif
};

qpCrashHandler *g_crashHandler = DE_NULL;

static void assertFailureCallback(const char *expr, const char *file, int line)
{
    /* Store info. */
    qpCrashInfo_set(&g_crashHandler->crashInfo, QP_CRASHTYPE_ASSERT, expr, file, line);

    /* Handle the crash. */
    if (g_crashHandler->crashHandlerFunc != DE_NULL)
        g_crashHandler->crashHandlerFunc(g_crashHandler, g_crashHandler->handlerUserPointer);
}

#if defined(QP_USE_SIGNAL_HANDLER)

static const SignalInfo *getSignalInfo(int sigNum)
{
    int ndx;
    for (ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_signals); ndx++)
    {
        if (s_signals[ndx].signalNum == sigNum)
            return &s_signals[ndx];
    }
    return DE_NULL;
}

static void signalHandler(int sigNum)
{
    const SignalInfo *info = getSignalInfo(sigNum);
    qpCrashType type       = info ? info->type : QP_CRASHTYPE_OTHER;
    const char *name       = info ? info->name : "Unknown signal";

    qpCrashInfo_set(&g_crashHandler->crashInfo, type, name, DE_NULL, 0);

    if (g_crashHandler->crashHandlerFunc != DE_NULL)
        g_crashHandler->crashHandlerFunc(g_crashHandler, g_crashHandler->handlerUserPointer);
}

#endif /* QP_USE_SIGNAL_HANDLER */

qpCrashHandler *qpCrashHandler_create(qpCrashHandlerFunc handlerFunc, void *userPointer)
{
    /* Allocate & initialize. */
    qpCrashHandler *handler = (qpCrashHandler *)deCalloc(sizeof(qpCrashHandler));
    DBGPRINT(("qpCrashHandler::create()\n"));
    if (!handler)
        return handler;

    DE_ASSERT(g_crashHandler == DE_NULL);

    handler->crashHandlerFunc   = handlerFunc ? handlerFunc : defaultCrashHandler;
    handler->handlerUserPointer = userPointer;

    qpCrashInfo_init(&handler->crashInfo);

    g_crashHandler = handler;

    /* DE_ASSERT callback. */
    deSetAssertFailureCallback(assertFailureCallback);

#if defined(QP_USE_SIGNAL_HANDLER)
    /* Register signal handlers. */
    {
        struct sigaction action;
        int sigNdx;

        sigemptyset(&action.sa_mask);
        action.sa_handler = signalHandler;
        action.sa_flags   = 0;

        for (sigNdx = 0; sigNdx < DE_LENGTH_OF_ARRAY(s_signals); sigNdx++)
            sigaction(s_signals[sigNdx].signalNum, &action, &handler->oldHandlers[sigNdx]);
    }
#endif

    return handler;
}

void qpCrashHandler_destroy(qpCrashHandler *handler)
{
    DBGPRINT(("qpCrashHandler::destroy()\n"));

    DE_ASSERT(g_crashHandler == handler);

    deSetAssertFailureCallback(DE_NULL);

#if defined(QP_USE_SIGNAL_HANDLER)
    /* Restore old handlers. */
    {
        int sigNdx;
        for (sigNdx = 0; sigNdx < DE_LENGTH_OF_ARRAY(s_signals); sigNdx++)
            sigaction(s_signals[sigNdx].signalNum, &handler->oldHandlers[sigNdx], DE_NULL);
    }
#endif

    g_crashHandler = DE_NULL;

    deFree(handler);
}

#if (DE_PTR_SIZE == 8)
#define PTR_FMT "0x%016"
#elif (DE_PTR_SIZE == 4)
#define PTR_FMT "0x%08"
#else
#error Unknwon DE_PTR_SIZE
#endif

void qpCrashHandler_writeCrashInfo(qpCrashHandler *crashHandler, qpWriteCrashInfoFunc writeInfo, void *userPtr)
{
    qpCrashInfo_write(&crashHandler->crashInfo, writeInfo, userPtr);

#if (DE_OS == DE_OS_UNIX)
    {
        char tmpFileName[] = "backtrace-XXXXXX";
        int tmpFile        = mkstemp(tmpFileName);

        if (tmpFile == -1)
        {
            writeInfoFormat(writeInfo, userPtr, "Failed to create tmpfile '%s' for the backtrace %s.", tmpFileName,
                            strerror(errno));
            return;
        }
        else
        {
            void *symbols[32];
            int symbolCount;
            int symbolNdx;

            /* Remove file from filesystem. */
            remove(tmpFileName);

            symbolCount = backtrace(symbols, DE_LENGTH_OF_ARRAY(symbols));
            backtrace_symbols_fd(symbols, symbolCount, tmpFile);

            if (lseek(tmpFile, 0, SEEK_SET) < 0)
            {
                writeInfoFormat(writeInfo, userPtr, "Failed to seek to the beginning of the trace file %s.",
                                strerror(errno));
                close(tmpFile);
                return;
            }

            for (symbolNdx = 0; symbolNdx < symbolCount; symbolNdx++)
            {
                char nameBuffer[256];
                size_t symbolNameLength = 0;
                char c;

                {
                    const int ret = snprintf(nameBuffer, DE_LENGTH_OF_ARRAY(nameBuffer), PTR_FMT PRIXPTR " : ",
                                             (uintptr_t)symbols[symbolNdx]);

                    if (ret < 0)
                    {
                        writeInfoFormat(writeInfo, userPtr, "Failed to print symbol pointer.");
                        symbolNameLength = 0;
                    }
                    else if (ret >= DE_LENGTH_OF_ARRAY(nameBuffer))
                    {
                        symbolNameLength                               = DE_LENGTH_OF_ARRAY(nameBuffer) - 1;
                        nameBuffer[DE_LENGTH_OF_ARRAY(nameBuffer) - 1] = '\0';
                    }
                    else
                        symbolNameLength = ret;
                }

                for (;;)
                {
                    if (read(tmpFile, &c, 1) == 1)
                    {
                        if (c == '\n')
                        {
                            /* Flush nameBuffer and move to next symbol. */
                            nameBuffer[symbolNameLength] = '\0';
                            writeInfo(userPtr, nameBuffer);
                            break;
                        }
                        else
                        {
                            /* Add character to buffer if there is still space left. */
                            if (symbolNameLength + 1 < DE_LENGTH_OF_ARRAY(nameBuffer))
                            {
                                nameBuffer[symbolNameLength] = c;
                                symbolNameLength++;
                            }
                        }
                    }
                    else
                    {
                        /* Flush nameBuffer. */
                        nameBuffer[symbolNameLength] = '\0';
                        writeInfo(userPtr, nameBuffer);

                        /* Temp file ended unexpectedly? */
                        writeInfoFormat(writeInfo, userPtr, "Unexpected EOF reading backtrace file '%s'", tmpFileName);
                        close(tmpFile);
                        tmpFile = -1;

                        break;
                    }
                }

                if (tmpFile == -1)
                    break;
            }

            if (tmpFile != -1)
                close(tmpFile);
        }
    }
#endif
}

#endif /* generic */
