// Copyright 2020 The Tint Authors.
//
// 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.

#include "src/tint/lang/spirv/writer/common/spv_dump.h"

#include "spirv-tools/libspirv.hpp"
#include "src/tint/lang/spirv/writer/common/binary_writer.h"

namespace tint::spirv::writer {

std::string Disassemble(const std::vector<uint32_t>& data, uint32_t options /* = 0u */) {
    std::string spv_errors;
    spv_target_env target_env = SPV_ENV_VULKAN_1_1;

    auto msg_consumer = [&spv_errors](spv_message_level_t level, const char*,
                                      const spv_position_t& position, const char* message) {
        switch (level) {
            case SPV_MSG_FATAL:
            case SPV_MSG_INTERNAL_ERROR:
            case SPV_MSG_ERROR:
                spv_errors +=
                    "error: line " + std::to_string(position.index) + ": " + message + "\n";
                break;
            case SPV_MSG_WARNING:
                spv_errors +=
                    "warning: line " + std::to_string(position.index) + ": " + message + "\n";
                break;
            case SPV_MSG_INFO:
                spv_errors +=
                    "info: line " + std::to_string(position.index) + ": " + message + "\n";
                break;
            case SPV_MSG_DEBUG:
                break;
        }
    };

    spvtools::SpirvTools tools(target_env);
    tools.SetMessageConsumer(msg_consumer);

    std::string result;
    if (!tools.Disassemble(data, &result, SPV_BINARY_TO_TEXT_OPTION_NO_HEADER | options)) {
        return "*** Invalid SPIR-V ***\n" + spv_errors;
    }
    return result;
}

std::string DumpModule(Module& module) {
    BinaryWriter writer;
    writer.WriteHeader(module.IdBound());
    writer.WriteModule(&module);
    return Disassemble(writer.Result());
}

std::string DumpInstruction(const Instruction& inst) {
    BinaryWriter writer;
    writer.WriteHeader(kDefaultMaxIdBound);
    writer.WriteInstruction(inst);
    return Disassemble(writer.Result());
}

std::string DumpInstructions(const InstructionList& insts) {
    BinaryWriter writer;
    writer.WriteHeader(kDefaultMaxIdBound);
    for (const auto& inst : insts) {
        writer.WriteInstruction(inst);
    }
    return Disassemble(writer.Result());
}

}  // namespace tint::spirv::writer
