/* Copyright (c) 2021 The Khronos Group Inc.
 * Copyright (c) 2021 Valve Corporation
 * Copyright (c) 2021 LunarG, Inc.
 * Copyright (C) 2021 Google Inc.
 *
 * 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.
 *
 * Author: Jeremy Gebben <jeremyg@lunarg.com>
 */
#include "core_error_location.h"
#include <map>

namespace core_error {
#define FUNC_ENTRY(_v) \
    { Func::_v, #_v }
const std::string& String(Func func) {
    static const std::map<Func, std::string> table{
        {Func::Empty, ""},
        FUNC_ENTRY(vkQueueSubmit),
        FUNC_ENTRY(vkQueueSubmit2KHR),
        FUNC_ENTRY(vkCmdSetEvent),
        FUNC_ENTRY(vkCmdSetEvent2KHR),
        FUNC_ENTRY(vkCmdResetEvent),
        FUNC_ENTRY(vkCmdResetEvent2KHR),
        FUNC_ENTRY(vkCmdPipelineBarrier),
        FUNC_ENTRY(vkCmdPipelineBarrier2KHR),
        FUNC_ENTRY(vkCmdWaitEvents),
        FUNC_ENTRY(vkCmdWaitEvents2KHR),
        FUNC_ENTRY(vkCmdWriteTimestamp),
        FUNC_ENTRY(vkCmdWriteTimestamp2KHR),
        FUNC_ENTRY(vkCreateRenderPass),
        FUNC_ENTRY(vkCreateRenderPass2),
        FUNC_ENTRY(vkQueueBindSparse),
        FUNC_ENTRY(vkSignalSemaphore),
    };
    const auto entry = table.find(func);
    assert(entry != table.end());
    return entry->second;
}

#define STRUCT_ENTRY(_v) \
    { Struct::_v, #_v }
const std::string& String(Struct structure) {
    static const std::map<Struct, std::string> table{
        {Struct::Empty, ""},
        STRUCT_ENTRY(VkMemoryBarrier),
        STRUCT_ENTRY(VkMemoryBarrier2KHR),
        STRUCT_ENTRY(VkBufferMemoryBarrier),
        STRUCT_ENTRY(VkImageMemoryBarrier),
        STRUCT_ENTRY(VkBufferMemoryBarrier2KHR),
        STRUCT_ENTRY(VkImageMemoryBarrier2KHR),
        STRUCT_ENTRY(VkSubmitInfo),
        STRUCT_ENTRY(VkSubmitInfo2KHR),
        STRUCT_ENTRY(VkCommandBufferSubmitInfoKHR),
        STRUCT_ENTRY(VkSubpassDependency),
        STRUCT_ENTRY(VkSubpassDependency2),
        STRUCT_ENTRY(VkBindSparseInfo),
        STRUCT_ENTRY(VkSemaphoreSignalInfo),
    };
    const auto entry = table.find(structure);
    assert(entry != table.end());
    return entry->second;
}

#define FIELD_ENTRY(_v) \
    { Field::_v, #_v }
const std::string& String(Field field) {
    static const std::map<Field, std::string> table{
        {Field::Empty, ""},
        FIELD_ENTRY(oldLayout),
        FIELD_ENTRY(newLayout),
        FIELD_ENTRY(image),
        FIELD_ENTRY(buffer),
        FIELD_ENTRY(pMemoryBarriers),
        FIELD_ENTRY(pBufferMemoryBarriers),
        FIELD_ENTRY(pImageMemoryBarriers),
        FIELD_ENTRY(offset),
        FIELD_ENTRY(size),
        FIELD_ENTRY(subresourceRange),
        FIELD_ENTRY(srcAccessMask),
        FIELD_ENTRY(dstAccessMask),
        FIELD_ENTRY(srcStageMask),
        FIELD_ENTRY(dstStageMask),
        FIELD_ENTRY(pNext),
        FIELD_ENTRY(pWaitDstStageMask),
        FIELD_ENTRY(pWaitSemaphores),
        FIELD_ENTRY(pSignalSemaphores),
        FIELD_ENTRY(pWaitSemaphoreInfos),
        FIELD_ENTRY(pWaitSemaphoreValues),
        FIELD_ENTRY(pSignalSemaphoreInfos),
        FIELD_ENTRY(pSignalSemaphoreValues),
        FIELD_ENTRY(stage),
        FIELD_ENTRY(stageMask),
        FIELD_ENTRY(value),
        FIELD_ENTRY(pCommandBuffers),
        FIELD_ENTRY(pSubmits),
        FIELD_ENTRY(pCommandBufferInfos),
        FIELD_ENTRY(semaphore),
        FIELD_ENTRY(commandBuffer),
        FIELD_ENTRY(dependencyFlags),
        FIELD_ENTRY(pDependencyInfo),
        FIELD_ENTRY(pDependencyInfos),
        FIELD_ENTRY(srcQueueFamilyIndex),
        FIELD_ENTRY(dstQueueFamilyIndex),
        FIELD_ENTRY(queryPool),
        FIELD_ENTRY(pDependencies),
        FIELD_ENTRY(pipelineStage),
    };
    const auto entry = table.find(field);
    assert(entry != table.end());
    return entry->second;
}

LocationCapture::LocationCapture(const Location& loc) { Capture(loc, 1); }

const Location* LocationCapture::Capture(const Location& loc, CaptureStore::size_type depth) {
    const Location* prev_capture = nullptr;
    if (loc.prev) {
        prev_capture = Capture(*loc.prev, depth + 1);
    } else {
        capture.reserve(depth);
    }

    capture.emplace_back(loc);
    capture.back().prev = prev_capture;
    return &(capture.back());
}

void Location::AppendFields(std::ostream& out) const {
    if (prev) {
        prev->AppendFields(out);
        out << ".";
    }
    out << String(field);
    if (index != Location::kNoIndex) {
        out << "[" << index << "]";
    }
}

bool operator==(const Key& key, const Location& loc) {
    assert(key.function != Func::Empty || key.structure != Struct::Empty);
    assert(loc.function != Func::Empty);
    if (key.function != Func::Empty) {
        if (key.function != loc.function) {
            return false;
        }
    }
    if (key.structure != Struct::Empty) {
        if (key.structure != loc.structure) {
            return false;
        }
    }
    if (key.field == Field::Empty) {
        return true;
    }
    if (key.field == loc.field) {
        return true;
    }
    if (key.recurse_field) {
        const Location *prev = loc.prev;
        while (prev != nullptr) {
            if (key.field == prev->field) {
                return true;
            }
            prev = prev->prev;
        }
    }
    return false;
}

}  // namespace core_error
