//
// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// Debug.cpp: Defines debug state used for GL_KHR_debug

#include "libANGLE/Debug.h"

#include "common/debug.h"

#include <algorithm>
#include <tuple>

namespace
{
const char *GLSeverityToString(GLenum severity)
{
    switch (severity)
    {
        case GL_DEBUG_SEVERITY_HIGH:
            return "HIGH";
        case GL_DEBUG_SEVERITY_MEDIUM:
            return "MEDIUM";
        case GL_DEBUG_SEVERITY_LOW:
            return "LOW";
        case GL_DEBUG_SEVERITY_NOTIFICATION:
        default:
            return "NOTIFICATION";
    }
}

const char *EGLMessageTypeToString(egl::MessageType messageType)
{
    switch (messageType)
    {
        case egl::MessageType::Critical:
            return "CRITICAL";
        case egl::MessageType::Error:
            return "ERROR";
        case egl::MessageType::Warn:
            return "WARNING";
        case egl::MessageType::Info:
        default:
            return "INFO";
    }
}

const char *GLMessageTypeToString(GLenum type)
{
    switch (type)
    {
        case GL_DEBUG_TYPE_ERROR:
            return "error";
        case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
            return "deprecated behavior";
        case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
            return "undefined behavior";
        case GL_DEBUG_TYPE_PORTABILITY:
            return "portability";
        case GL_DEBUG_TYPE_PERFORMANCE:
            return "performance";
        case GL_DEBUG_TYPE_MARKER:
            return "marker";
        case GL_DEBUG_TYPE_PUSH_GROUP:
            return "start of group";
        case GL_DEBUG_TYPE_POP_GROUP:
            return "end of group";
        case GL_DEBUG_TYPE_OTHER:
        default:
            return "other message";
    }
}
}  // namespace

namespace gl
{

Debug::Control::Control() {}

Debug::Control::~Control() {}

Debug::Control::Control(const Control &other) = default;

Debug::Group::Group() {}

Debug::Group::~Group() {}

Debug::Group::Group(const Group &other) = default;

Debug::Debug(bool initialDebugState)
    : mOutputEnabled(initialDebugState),
      mCallbackFunction(nullptr),
      mCallbackUserParam(nullptr),
      mMessages(),
      mMaxLoggedMessages(0),
      mOutputSynchronous(false),
      mGroups()
{
    pushDefaultGroup();
}

Debug::~Debug() {}

void Debug::setMaxLoggedMessages(GLuint maxLoggedMessages)
{
    mMaxLoggedMessages = maxLoggedMessages;
}

void Debug::setOutputEnabled(bool enabled)
{
    mOutputEnabled = enabled;
}

bool Debug::isOutputEnabled() const
{
    return mOutputEnabled;
}

void Debug::setOutputSynchronous(bool synchronous)
{
    mOutputSynchronous = synchronous;
}

bool Debug::isOutputSynchronous() const
{
    return mOutputSynchronous;
}

void Debug::setCallback(GLDEBUGPROCKHR callback, const void *userParam)
{
    mCallbackFunction  = callback;
    mCallbackUserParam = userParam;
}

GLDEBUGPROCKHR Debug::getCallback() const
{
    return mCallbackFunction;
}

const void *Debug::getUserParam() const
{
    return mCallbackUserParam;
}

void Debug::insertMessage(GLenum source,
                          GLenum type,
                          GLuint id,
                          GLenum severity,
                          const std::string &message,
                          gl::LogSeverity logSeverity) const
{
    std::string messageCopy(message);
    insertMessage(source, type, id, severity, std::move(messageCopy), logSeverity);
}

void Debug::insertMessage(GLenum source,
                          GLenum type,
                          GLuint id,
                          GLenum severity,
                          std::string &&message,
                          gl::LogSeverity logSeverity) const
{
    {
        // output all messages to the debug log
        const char *messageTypeString = GLMessageTypeToString(type);
        const char *severityString    = GLSeverityToString(severity);
        std::ostringstream messageStream;
        messageStream << "GL " << messageTypeString << ": " << severityString << ": " << message;
        switch (logSeverity)
        {
            case gl::LOG_FATAL:
                FATAL() << messageStream.str();
                break;
            case gl::LOG_ERR:
                ERR() << messageStream.str();
                break;
            case gl::LOG_WARN:
                WARN() << messageStream.str();
                break;
            case gl::LOG_INFO:
                INFO() << messageStream.str();
                break;
            case gl::LOG_EVENT:
                ANGLE_LOG(EVENT) << messageStream.str();
                break;
        }
    }

    if (!isMessageEnabled(source, type, id, severity))
    {
        return;
    }

    if (mCallbackFunction != nullptr)
    {
        // TODO(geofflang) Check the synchronous flag and potentially flush messages from another
        // thread.
        mCallbackFunction(source, type, id, severity, static_cast<GLsizei>(message.length()),
                          message.c_str(), mCallbackUserParam);
    }
    else
    {
        if (mMessages.size() >= mMaxLoggedMessages)
        {
            // Drop messages over the limit
            return;
        }

        Message m;
        m.source   = source;
        m.type     = type;
        m.id       = id;
        m.severity = severity;
        m.message  = std::move(message);

        mMessages.push_back(std::move(m));
    }
}

size_t Debug::getMessages(GLuint count,
                          GLsizei bufSize,
                          GLenum *sources,
                          GLenum *types,
                          GLuint *ids,
                          GLenum *severities,
                          GLsizei *lengths,
                          GLchar *messageLog)
{
    size_t messageCount       = 0;
    size_t messageStringIndex = 0;
    while (messageCount <= count && !mMessages.empty())
    {
        const Message &m = mMessages.front();

        if (messageLog != nullptr)
        {
            // Check that this message can fit in the message buffer
            if (messageStringIndex + m.message.length() + 1 > static_cast<size_t>(bufSize))
            {
                break;
            }

            std::copy(m.message.begin(), m.message.end(), messageLog + messageStringIndex);
            messageStringIndex += m.message.length();

            messageLog[messageStringIndex] = '\0';
            messageStringIndex += 1;
        }

        if (sources != nullptr)
        {
            sources[messageCount] = m.source;
        }

        if (types != nullptr)
        {
            types[messageCount] = m.type;
        }

        if (ids != nullptr)
        {
            ids[messageCount] = m.id;
        }

        if (severities != nullptr)
        {
            severities[messageCount] = m.severity;
        }

        if (lengths != nullptr)
        {
            lengths[messageCount] = static_cast<GLsizei>(m.message.length());
        }

        mMessages.pop_front();

        messageCount++;
    }

    return messageCount;
}

size_t Debug::getNextMessageLength() const
{
    return mMessages.empty() ? 0 : mMessages.front().message.length();
}

size_t Debug::getMessageCount() const
{
    return mMessages.size();
}

void Debug::setMessageControl(GLenum source,
                              GLenum type,
                              GLenum severity,
                              std::vector<GLuint> &&ids,
                              bool enabled)
{
    Control c;
    c.source   = source;
    c.type     = type;
    c.severity = severity;
    c.ids      = std::move(ids);
    c.enabled  = enabled;

    auto &controls = mGroups.back().controls;
    controls.push_back(std::move(c));
}

void Debug::pushGroup(GLenum source, GLuint id, std::string &&message)
{
    insertMessage(source, GL_DEBUG_TYPE_PUSH_GROUP, id, GL_DEBUG_SEVERITY_NOTIFICATION,
                  std::string(message), gl::LOG_INFO);

    Group g;
    g.source  = source;
    g.id      = id;
    g.message = std::move(message);
    mGroups.push_back(std::move(g));
}

void Debug::popGroup()
{
    // Make sure the default group is not about to be popped
    ASSERT(mGroups.size() > 1);

    Group g = mGroups.back();
    mGroups.pop_back();

    insertMessage(g.source, GL_DEBUG_TYPE_POP_GROUP, g.id, GL_DEBUG_SEVERITY_NOTIFICATION,
                  g.message, gl::LOG_INFO);
}

size_t Debug::getGroupStackDepth() const
{
    return mGroups.size();
}

bool Debug::isMessageEnabled(GLenum source, GLenum type, GLuint id, GLenum severity) const
{
    if (!mOutputEnabled)
    {
        return false;
    }

    for (auto groupIter = mGroups.rbegin(); groupIter != mGroups.rend(); groupIter++)
    {
        const auto &controls = groupIter->controls;
        for (auto controlIter = controls.rbegin(); controlIter != controls.rend(); controlIter++)
        {
            const auto &control = *controlIter;

            if (control.source != GL_DONT_CARE && control.source != source)
            {
                continue;
            }

            if (control.type != GL_DONT_CARE && control.type != type)
            {
                continue;
            }

            if (control.severity != GL_DONT_CARE && control.severity != severity)
            {
                continue;
            }

            if (!control.ids.empty() &&
                std::find(control.ids.begin(), control.ids.end(), id) == control.ids.end())
            {
                continue;
            }

            return control.enabled;
        }
    }

    return true;
}

void Debug::pushDefaultGroup()
{
    Group g;
    g.source  = GL_NONE;
    g.id      = 0;
    g.message = "";

    Control c0;
    c0.source   = GL_DONT_CARE;
    c0.type     = GL_DONT_CARE;
    c0.severity = GL_DONT_CARE;
    c0.enabled  = true;
    g.controls.push_back(std::move(c0));

    Control c1;
    c1.source   = GL_DONT_CARE;
    c1.type     = GL_DONT_CARE;
    c1.severity = GL_DEBUG_SEVERITY_LOW;
    c1.enabled  = false;
    g.controls.push_back(std::move(c1));

    mGroups.push_back(std::move(g));
}
}  // namespace gl

namespace egl
{

namespace
{
angle::PackedEnumBitSet<MessageType> GetDefaultMessageTypeBits()
{
    angle::PackedEnumBitSet<MessageType> result;
    result.set(MessageType::Critical);
    result.set(MessageType::Error);
    return result;
}
}  // anonymous namespace

Debug::Debug() : mCallback(nullptr), mEnabledMessageTypes(GetDefaultMessageTypeBits()) {}

void Debug::setCallback(EGLDEBUGPROCKHR callback, const AttributeMap &attribs)
{
    mCallback = callback;

    const angle::PackedEnumBitSet<MessageType> defaultMessageTypes = GetDefaultMessageTypeBits();
    if (mCallback != nullptr)
    {
        for (MessageType messageType : angle::AllEnums<MessageType>())
        {
            mEnabledMessageTypes[messageType] =
                (attribs.getAsInt(egl::ToEGLenum(messageType), defaultMessageTypes[messageType]) ==
                 EGL_TRUE);
        }
    }
}

EGLDEBUGPROCKHR Debug::getCallback() const
{
    return mCallback;
}

bool Debug::isMessageTypeEnabled(MessageType type) const
{
    return mEnabledMessageTypes[type];
}

void Debug::insertMessage(EGLenum error,
                          const char *command,
                          MessageType messageType,
                          EGLLabelKHR threadLabel,
                          EGLLabelKHR objectLabel,
                          const std::string &message) const
{
    {
        // output all messages to the debug log
        const char *messageTypeString = EGLMessageTypeToString(messageType);
        std::ostringstream messageStream;
        messageStream << "EGL " << messageTypeString << ": " << command << ": " << message;
        INFO() << messageStream.str();
    }

    // TODO(geofflang): Lock before checking the callback. http://anglebug.com/2464
    if (mCallback && isMessageTypeEnabled(messageType))
    {
        mCallback(error, command, egl::ToEGLenum(messageType), threadLabel, objectLabel,
                  message.c_str());
    }
}

}  // namespace egl
