/*
 * Copyright 2021 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#ifndef SkVMVisualizer_DEFINED
#define SkVMVisualizer_DEFINED

#include "include/core/SkString.h"
#include "include/core/SkTypes.h"
#include "include/private/SkTArray.h"
#include "include/private/SkTHash.h"
#include "src/core/SkVM.h"

#include <cstddef>
#include <type_traits>
#include <vector>

class SkWStream;
namespace SkSL { class SkVMDebugTrace; }

namespace skvm::viz {
    enum InstructionFlags : uint8_t {
        kNormal = 0x00,
        kHoisted = 0x01,
        kDead = 0x02,
    };

    struct MachineCommand {
        size_t address;
        SkString label;
        SkString command;
        SkString extra;
    };

    struct Instruction {
        InstructionFlags kind = InstructionFlags::kNormal;
        // Machine commands range (for disassembling):
        size_t startCode = 0;
        size_t endCode = 0;
        int instructionIndex; // index in the actual instructions list
        int duplicates = 0;   // number of duplicates;
                              // -1 means it's a duplicate itself; 0 - it does not have dups
        skvm::Instruction instruction;
        bool operator == (const Instruction& o) const;
        SkString classes() const;
    };

    struct InstructionHash {
        uint32_t operator()(const Instruction& i) const;
    };

    class Visualizer {
    public:
        explicit Visualizer(SkSL::SkVMDebugTrace* debugInfo);
        ~Visualizer() = default;
        void dump(SkWStream* output, const char* code);
        void markAsDeadCode(std::vector<bool>& live, const std::vector<int>& newIds);
        void finalize(const std::vector<skvm::Instruction>& all,
                      const std::vector<skvm::OptimizedInstruction>& optimized);
        void addInstructions(std::vector<skvm::Instruction>& program);
        void markAsDuplicate(int origin, int id) {
            ++fInstructions[origin].duplicates;
        }
        void addInstruction(Instruction skvm);
        void addMachineCommands(int id, size_t start, size_t end);
        SkString V(int reg) const;
    private:
        void parseDisassembler(SkWStream* output, const char* code);
        void dumpInstruction(int id) const;
        void dumpHead() const;
        void dumpTail() const;
        void formatVV(const char* op, int v1, int v2) const;
        void formatPV(const char* op, int imm, int v1) const;
        void formatPVV(const char* op, int imm, int v1, int v2) const;
        void formatPVVVV(const char* op, int imm, int v1, int v2, int v3, int v4) const;
        void formatA_(int id, const char* op) const;
        void formatA_P(int id, const char* op, int imm) const;
        void formatA_PH(int id, const char* op, int immA, int immB) const;
        void formatA_PHH(int id, const char* op, int immA, int immB, int immC) const;
        void formatA_PHV(int id, const char* op, int immA, int immB, int v) const;
        void formatA_S(int id, const char* op, int imm) const;
        void formatA_V(int id, const char* op, int v) const;
        void formatA_VV(int id, const char* op, int v1, int v2) const;
        void formatA_VVV(int id, const char* op,  int v1, int v2, int v3) const;
        void formatA_VC(int id, const char* op,  int v, int imm) const;

        void writeText(const char* format, ...) const SK_PRINTF_LIKE(2, 3);
#if defined(SK_ENABLE_SKSL)
        SkSL::SkVMDebugTrace* fDebugInfo;
#endif
        SkTHashMap<Instruction, size_t, InstructionHash> fIndex;
        SkTArray<Instruction> fInstructions;
        SkWStream* fOutput;
        SkTHashMap<int, size_t> fToDisassembler;
        SkTArray<MachineCommand> fAsm;
        mutable size_t fAsmLine = 0;
        size_t fAsmStart = 0;
        size_t fAsmEnd = 0;
    };
} // namespace skvm::viz

namespace sknonstd {
template <typename T> struct is_bitmask_enum;
template <> struct is_bitmask_enum<skvm::viz::InstructionFlags> : std::true_type {};
}  // namespace sknonstd

#endif // SkVMVisualizer_DEFINED
