//
// 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 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) const
{
    std::string messageCopy(message);
    insertMessage(source, type, id, severity, std::move(messageCopy));
}

void Debug::insertMessage(GLenum source,
                          GLenum type,
                          GLuint id,
                          GLenum severity,
                          std::string &&message) const
{
    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));

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

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
{
    // 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
