// 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_test.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
