/*
 * Copyright 2021 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "src/utils/SkVMVisualizer.h"

#include "include/core/SkStream.h"
#include "include/private/SkOpts_spi.h"
#include "src/core/SkStreamPriv.h"

#if defined(SK_ENABLE_SKSL)
#include "src/sksl/tracing/SkVMDebugTrace.h"
#endif

#include <algorithm>
#include <cstdarg>
#include <sstream>
#include <string>
#include <utility>

namespace {

size_t get_addr(const char* str) {
    size_t addr;
    std::istringstream ss(str);
    ss >> std::hex >> addr;
    SkASSERT(!ss.fail());
    return addr;
}

}

namespace skvm::viz {

#if defined(SK_ENABLE_SKSL)
Visualizer::Visualizer(SkSL::SkVMDebugTrace* debugInfo) : fDebugInfo(debugInfo), fOutput(nullptr) {}
#else
Visualizer::Visualizer(SkSL::SkVMDebugTrace* debugInfo) : fOutput(nullptr) {}
#endif

bool Instruction::operator == (const Instruction& o) const {
    return this->kind == o.kind &&
           this->startCode == o.startCode &&
           this->endCode == o.endCode &&
           this->instructionIndex == o.instructionIndex &&
           this->instruction == o.instruction &&
           this->duplicates == o.duplicates;
}

SkString Instruction::classes() const {
    SkString result((kind & InstructionFlags::kDead) ? "dead" : "normal");
    if (duplicates > 0) result += " origin";
    if (duplicates < 0) result += " deduped";
    return result;
}

uint32_t InstructionHash::operator()(const Instruction& i) const {
    uint32_t hash = 0;
    hash = SkOpts::hash_fn(&i.kind, sizeof(i.kind), hash);
    hash = SkOpts::hash_fn(&i.instructionIndex, sizeof(i.instructionIndex), hash);
    hash = SkOpts::hash_fn(&i.instruction, sizeof(i.instruction), hash);
    return hash;
}

void Visualizer::parseDisassembler(SkWStream* output, const char* code) {
    if (code == nullptr) {
        fAsmLine = 0;
        return;
    }
    // Read the disassembled code from <_skvm_jit> until
    // the last command that is attached to the byte code
    // We skip all the prelude (main loop organizing and such)
    // generate the main loop running on vector values (keeping hoisted commands in place)
    // and skip the tail loop (which is the same as the main, only on scalar values)
    // We stop after the last byte code.
    SkTArray<SkString> commands;
    SkStrSplit(code, "\n", kStrict_SkStrSplitMode, &commands);
    for (const SkString& line : commands) {
        ++fAsmLine;
        if (line.find("<_skvm_jit>") >= 0) {
            break;
        }
    }

    if (fAsmLine < commands.size()) {
        const SkString& line = commands[fAsmLine];
        SkTArray<SkString> tokens;
        SkStrSplit(line.c_str(), "\t", kStrict_SkStrSplitMode, &tokens);
        if (tokens.size() >= 2 && tokens[0].size() > 1) {
            fAsmStart = get_addr(tokens[0].c_str());
        }
    }

    fAsmEnd += fAsmStart;
    for (size_t i = fAsmLine; i < commands.size(); ++i) {
        const SkString& line = commands[i];
        SkTArray<SkString> tokens;
        SkStrSplit(line.c_str(), "\t", kStrict_SkStrSplitMode, &tokens);
        size_t addr = 0;
        if (tokens.size() >= 2 && tokens[0].size() > 1) {
            addr = get_addr(tokens[0].c_str());
        }
        if (addr > fAsmEnd) {
            break;
        }
        addr -= fAsmStart;
        if (!fAsm.empty()) {
            MachineCommand& prev = fAsm.back();
            if (prev.command.isEmpty()) {
                int len = addr - prev.address;
                prev.command.printf("{ align %d bytes }", len);
            }
        }
        SkString command;
        for (size_t t = 2; t < tokens.size(); ++t) {
            command += tokens[t];
        }
        fAsm.push_back({addr, tokens[0], command, tokens[1]});
    }
    if (!fAsm.empty()) {
        MachineCommand& prev = fAsm.back();
        if (prev.command.isEmpty()) {
            int len = fInstructions.back().endCode - prev.address;
            prev.command.printf("{ align %d bytes }", len);
        }
    }
    fAsmLine = 0;
}

void Visualizer::dump(SkWStream* output, const char* code) {
    SkDebugfStream stream;
    fOutput = output ? output : &stream;
    this->parseDisassembler(output, code);
    this->dumpHead();
    for (size_t id = 0ul; id < fInstructions.size(); ++id) {
        this->dumpInstruction(id);
    }
    this->dumpTail();
}

void Visualizer::markAsDeadCode(std::vector<bool>& live, const std::vector<int>& newIds) {
    for (size_t id = 0ul; id < fInstructions.size(); ++id) {
        Instruction& instruction = fInstructions[id];
        if (instruction.instructionIndex < 0) {
            // We skip commands that are duplicates of some other commands
            // They either will be dead or alive together with the origin
            continue;
        }
        SkASSERT(instruction.instructionIndex < (int)live.size());
        if (live[instruction.instructionIndex]) {
            instruction.instructionIndex = newIds[instruction.instructionIndex];
            fToDisassembler[instruction.instructionIndex] = id;
        } else {
            instruction.kind
                    = static_cast<InstructionFlags>(instruction.kind | InstructionFlags::kDead);
            fToDisassembler[instruction.instructionIndex] = -1;
            // Anything negative meaning the command is duplicate/dead
            instruction.instructionIndex = -2;
        }
    }
}

void Visualizer::addInstructions(std::vector<skvm::Instruction>& program) {
    for (Val id = 0; id < (Val)program.size(); id++) {
        skvm::Instruction& instr = program[id];
        auto isDuplicate = instr.op == Op::duplicate;
        if (isDuplicate) {
            this->markAsDuplicate(instr.immA, id);
            instr = program[instr.immA];
        }
        this->addInstruction({
            viz::InstructionFlags::kNormal,
            /*startCode=*/0, /*endCode=0*/0,
            id,
            isDuplicate ? -1 : 0,
            instr
        });
    }
}

void Visualizer::addInstruction(Instruction skvm) {
    if (!touches_varying_memory(skvm.instruction.op)) {
        if (auto found = fIndex.find(skvm)) {
            auto& instruction = fInstructions[*found];
            ++(instruction.duplicates);
            return;
        }
    }
    fIndex.set(skvm, fInstructions.size());
    fToDisassembler.set(skvm.instructionIndex, fInstructions.size());
    fInstructions.emplace_back(std::move(skvm));
}

void Visualizer::finalize(const std::vector<skvm::Instruction>& all,
                              const std::vector<skvm::OptimizedInstruction>& optimized) {
    for (Val id = 0; id < (Val)all.size(); id++) {
        if (optimized[id].can_hoist) {
            size_t found = fToDisassembler[id];
            Instruction& instruction = fInstructions[found];
            instruction.kind =
                    static_cast<InstructionFlags>(instruction.kind | InstructionFlags::kHoisted);
        }
    }
}

void Visualizer::addMachineCommands(int id, size_t start, size_t end) {
    size_t found = fToDisassembler[id];
    Instruction& instruction = fInstructions[found];
    instruction.startCode = start;
    instruction.endCode = end;
    fAsmEnd = std::max(fAsmEnd, end);
}

SkString Visualizer::V(int reg) const {
    if (reg == -1) {
        return SkString("{optimized}");
    } else if (reg == -2) {
        return SkString("{dead code}");
    } else {
        return SkStringPrintf("v%d", reg);
    }
}

void Visualizer::formatVV(const char* op, int v1, int v2) const {
    this->writeText("%s %s, %s", op, V(v1).c_str(), V(v2).c_str());
}
void Visualizer::formatPV(const char* op, int imm, int v1) const {
    this->writeText("%s Ptr%d, %s", op, imm, V(v1).c_str());
}
void Visualizer::formatPVV(const char* op, int imm, int v1, int v2) const {
    this->writeText("%s Ptr%d, %s, %s", op, imm, V(v1).c_str(), V(v2).c_str());
}
void Visualizer::formatPVVVV(const char* op, int imm, int v1, int v2, int v3, int v4) const {
    this->writeText("%s Ptr%d, %s, %s, %s, %s",
              op, imm, V(v1).c_str(), V(v2).c_str(), V(v3).c_str(), V(v4).c_str());
}
void Visualizer::formatA_(int id, const char* op) const {
    writeText("%s = %s", V(id).c_str(), op);
}
void Visualizer::formatA_P(int id, const char* op, int imm) const {
    this->writeText("%s = %s Ptr%d", V(id).c_str(), op, imm);
}
void Visualizer::formatA_PH(int id, const char* op, int immA, int immB) const {
    this->writeText("%s = %s Ptr%d, %x", V(id).c_str(), op, immA, immB);
}
void Visualizer::formatA_PHH(int id, const char* op, int immA, int immB, int immC) const {
    this->writeText("%s = %s Ptr%d, %x, %x", V(id).c_str(), op, immA, immB, immC);
}
void Visualizer::formatA_PHV(int id, const char* op, int immA, int immB, int v) const {
    this->writeText("%s = %s Ptr%d, %x, %s", V(id).c_str(), op, immA, immB, V(v).c_str());
}
void Visualizer::formatA_S(int id, const char* op, int imm) const {
    float f;
    memcpy(&f, &imm, 4);
    char buffer[kSkStrAppendScalar_MaxSize];
    char* stop = SkStrAppendScalar(buffer, f);
    this->writeText("%s = %s %x (", V(id).c_str(), op, imm);
    fOutput->write(buffer, stop - buffer);
    this->writeText(")");
}
void Visualizer::formatA_V(int id, const char* op, int v) const {
    this->writeText("%s = %s %s", V(id).c_str(), op, V(v).c_str());
}
void Visualizer::formatA_VV(int id, const char* op, int v1, int v2) const {
    this->writeText("%s = %s %s, %s", V(id).c_str(), op, V(v1).c_str(), V(v2).c_str());
}
void Visualizer::formatA_VVV(int id, const char* op,  int v1, int v2, int v3) const {
    this->writeText(
            "%s = %s %s, %s, %s", V(id).c_str(), op, V(v1).c_str(), V(v2).c_str(), V(v3).c_str());
}
void Visualizer::formatA_VC(int id, const char* op,  int v, int imm) const {
    this->writeText("%s = %s %s, %d", V(id).c_str(), op, V(v).c_str(), imm);
}

void Visualizer::writeText(const char* format, ...) const {
    SkString message;
    va_list argp;
    va_start(argp, format);
    message.appendVAList(format, argp);
    va_end(argp);
    fOutput->writeText(message.c_str());
}

void Visualizer::dumpInstruction(int id0) const {
    const Instruction& instruction = fInstructions[id0];
    const int id = instruction.instructionIndex;
    const int x = instruction.instruction.x,
              y = instruction.instruction.y,
              z = instruction.instruction.z,
              w = instruction.instruction.w;
    const int immA = instruction.instruction.immA,
              immB = instruction.instruction.immB,
              immC = instruction.instruction.immC;
#if defined(SK_ENABLE_SKSL)
    if (instruction.instruction.op == skvm::Op::trace_line) {
        SkASSERT(fDebugInfo != nullptr);
        SkASSERT(immA >= 0 && immB <= (int)fDebugInfo->fSource.size());
        this->writeText("<tr class='source'><td class='mask'></td><td colspan=2>// %s</td></tr>\n",
                        fDebugInfo->fSource[immB].c_str());
        return;
    } else if (instruction.instruction.op == skvm::Op::trace_var ||
               instruction.instruction.op == skvm::Op::trace_scope) {
        // TODO: We can add some visualization here
        return;
    } else if (instruction.instruction.op == skvm::Op::trace_enter) {
        SkASSERT(fDebugInfo != nullptr);
        SkASSERT(immA >= 0 && immA <= (int)fDebugInfo->fFuncInfo.size());
        std::string& func = fDebugInfo->fFuncInfo[immA].name;
        SkString mask;
        mask.printf(immC == 1 ? "%s(-1)" : "%s", V(x).c_str());
        this->writeText(
                "<tr class='source'><td class='mask'>&#8618;%s</td><td colspan=2>%s</td></tr>\n",
                mask.c_str(),
                func.c_str());
        return;
    } else if (instruction.instruction.op == skvm::Op::trace_exit) {
        SkASSERT(fDebugInfo != nullptr);
        SkASSERT(immA >= 0 && immA <= (int)fDebugInfo->fFuncInfo.size());
        std::string& func = fDebugInfo->fFuncInfo[immA].name;
        SkString mask;
        mask.printf(immC == 1 ? "%s(-1)" : "%s", V(x).c_str());
        this->writeText(
                "<tr class='source'><td class='mask'>&#8617;%s</td><td colspan=2>%s</td></tr>\n",
                mask.c_str(),
                func.c_str());
        return;
    }
#endif // defined(SK_ENABLE_SKSL)
    // No label, to the operation
    SkString label;
    if ((instruction.kind & InstructionFlags::kHoisted) != 0) {
        label.set("&#8593;&#8593;&#8593; ");
    }
    if (instruction.duplicates > 0) {
        label.appendf("*%d", instruction.duplicates + 1);
    }
    SkString classes = instruction.classes();
    this->writeText("<tr class='%s'><td>%s</td><td>", classes.c_str(), label.c_str());
    // Operation
    switch (instruction.instruction.op) {
        case skvm::Op::assert_true:   formatVV("assert_true", x, y);                  break;
        case skvm::Op::store8:        formatPV("store8", immA, x);                    break;
        case skvm::Op::store16:       formatPV("store16", immA, x);                   break;
        case skvm::Op::store32:       formatPV("store32", immA, x);                   break;
        case skvm::Op::store64:       formatPVV("store64", immA, x, y);               break;
        case skvm::Op::store128:      formatPVVVV("store128", immA, x, y, z, w);      break;
        case skvm::Op::index:         formatA_(id, "index");                          break;
        case skvm::Op::load8:         formatA_P(id, "load8", immA);                   break;
        case skvm::Op::load16:        formatA_P(id, "load16", immA);                  break;
        case skvm::Op::load32:        formatA_P(id, "load32", immA);                  break;
        case skvm::Op::load64:        formatA_PH(id, "load64", immA, immB);           break;
        case skvm::Op::load128:       formatA_PH(id, "load128", immA, immB);          break;
        case skvm::Op::gather8:       formatA_PHV(id, "gather8", immA, immB, x);      break;
        case skvm::Op::gather16:      formatA_PHV(id, "gather16", immA, immB, x);     break;
        case skvm::Op::gather32:      formatA_PHV(id, "gather32", immA, immB, x);     break;
        case skvm::Op::uniform32:     formatA_PH(id, "uniform32", immA, immB);        break;
        case skvm::Op::array32:       formatA_PHH(id, "array32", immA, immB, immC);   break;
        case skvm::Op::splat:         formatA_S(id, "splat", immA);                   break;
        case skvm::Op:: add_f32:      formatA_VV(id, "add_f32", x, y);                break;
        case skvm::Op:: sub_f32:      formatA_VV(id, "sub_f32", x, y);                break;
        case skvm::Op:: mul_f32:      formatA_VV(id, "mul_f32", x, y);                break;
        case skvm::Op:: div_f32:      formatA_VV(id, "div_f32", x, y);                break;
        case skvm::Op:: min_f32:      formatA_VV(id, "min_f32", x, y);                break;
        case skvm::Op:: max_f32:      formatA_VV(id, "max_f32", x, y);                break;
        case skvm::Op:: fma_f32:      formatA_VVV(id, "fma_f32", x, y, z);            break;
        case skvm::Op:: fms_f32:      formatA_VVV(id, "fms_f32", x, y, z);            break;
        case skvm::Op::fnma_f32:      formatA_VVV(id, "fnma_f32", x, y, z);           break;
        case skvm::Op::sqrt_f32:      formatA_V(id, "sqrt_f32", x);                   break;
        case skvm::Op:: eq_f32:       formatA_VV(id, "eq_f32", x, y);                 break;
        case skvm::Op::neq_f32:       formatA_VV(id, "neq_f32", x, y);                break;
        case skvm::Op:: gt_f32:       formatA_VV(id, "gt_f32", x, y);                 break;
        case skvm::Op::gte_f32:       formatA_VV(id, "gte_f32", x, y);                break;
        case skvm::Op::add_i32:       formatA_VV(id, "add_i32", x, y);                break;
        case skvm::Op::sub_i32:       formatA_VV(id, "sub_i32", x, y);                break;
        case skvm::Op::mul_i32:       formatA_VV(id, "mul_i32", x, y);                break;
        case skvm::Op::shl_i32:       formatA_VC(id, "shl_i32", x, immA);             break;
        case skvm::Op::shr_i32:       formatA_VC(id, "shr_i32", x, immA);             break;
        case skvm::Op::sra_i32:       formatA_VC(id, "sra_i32", x, immA);             break;
        case skvm::Op::eq_i32:        formatA_VV(id, "eq_i32", x, y);                 break;
        case skvm::Op::gt_i32:        formatA_VV(id, "gt_i32", x, y);                 break;
        case skvm::Op::bit_and:       formatA_VV(id, "bit_and", x, y);                break;
        case skvm::Op::bit_or:        formatA_VV(id, "bit_or", x, y);                 break;
        case skvm::Op::bit_xor:       formatA_VV(id, "bit_xor", x, y);                break;
        case skvm::Op::bit_clear:     formatA_VV(id, "bit_clear", x, y);              break;
        case skvm::Op::select:        formatA_VVV(id, "select", x, y, z);             break;
        case skvm::Op::ceil:          formatA_V(id, "ceil", x);                       break;
        case skvm::Op::floor:         formatA_V(id, "floor", x);                      break;
        case skvm::Op::to_f32:        formatA_V(id, "to_f32", x);                     break;
        case skvm::Op::to_fp16:       formatA_V(id, "to_fp16", x);                    break;
        case skvm::Op::from_fp16:     formatA_V(id, "from_fp16", x);                  break;
        case skvm::Op::trunc:         formatA_V(id, "trunc", x);                      break;
        case skvm::Op::round:         formatA_V(id, "round", x);                      break;
        default: SkASSERT(false);
    }
    // Generation
    if ((instruction.kind & InstructionFlags::kDead) == 0) {
        struct Compare
        {
            bool operator() (const MachineCommand& c, std::pair<size_t, size_t> p) const
                            { return c.address < p.first; }
            bool operator() (std::pair<size_t, size_t> p, const MachineCommand& c) const
                            { return p.second <= c.address; }
        };

        std::pair<size_t, size_t> range(instruction.startCode, instruction.endCode);
        auto commands = std::equal_range(fAsm.begin(), fAsm.end(), range, Compare{ });
        for (const MachineCommand* line = commands.first; line != commands.second; ++line) {
            this->writeText("</td></tr>\n<tr class='machine'><td>%s</td><td colspan='2'>%s",
                            line->label.c_str(),
                            line->command.c_str());
        }
        fAsmLine = commands.second - fAsm.begin();
    }
    this->writeText("</td></tr>\n");
}

void Visualizer::dumpHead() const {
    this->writeText("%s",
    "<html>\n"
    "<head>\n"
    "   <title>SkVM Disassembler Output</title>\n"
    "   <style>\n"
    "   button { border-style: none; font-size: 10px; background-color: lightpink; }\n"
    "   table { text-align: left; }\n"
    "   table th { background-color: lightgray; }\n"
    "   .dead, .dead1 { color: lightgray; text-decoration: line-through; }\n"
    "   .normal, .normal1 { }\n"
    "   .origin, .origin1 { font-weight: bold; }\n"
    "   .source, .source1 { color: darkblue; }\n"
    "   .mask, .mask1 { color: green; }\n"
    "   .comments, .comments1 { }\n"
    "   .machine, .machine1 { color: lightblue; }\n"
    "   </style>\n"
    "    <script>\n"
    "    function initializeButton(className) {\n"
    "      var btn = document.getElementById(className);\n"
    "      var elems = document.getElementsByClassName(className);\n"
    "      if (elems == undefined || elems.length == 0) {\n"
    "        btn.disabled = true;\n"
    "        btn.innerText = \"None\";\n"
    "        btn.style.background = \"lightgray\";\n"
    "        return;\n"
    "      }\n"
    "    };\n"
    "    function initialize() {\n"
    "      initializeButton('normal');\n"
    "      initializeButton('source');\n"
    "      initializeButton('dead');\n"
    "      initializeButton('machine');\n"
    "    };\n"
    "  </script>\n"
    "</head>\n"
    "<body onload='initialize();'>\n"
    "    <script>\n"
    "    function toggle(btn, className) {\n"
    "      var elems = document.getElementsByClassName(className);\n"
    "      for (var i = 0; i < elems.length; i++) {\n"
    "        var elem = elems.item(i);\n"
    "        if (elem.style.display === \"\") {\n"
    "            elem.style.display = \"none\";\n"
    "            btn.innerText = \"Show\";\n"
    "            btn.style.background = \"lightcyan\";\n"
    "        } else {\n"
    "            elem.style.display = \"\";\n"
    "            btn.innerText = \"Hide\";\n"
    "            btn.style.background = \"lightpink\";\n"
    "        }\n"
    "      }\n"
    "    };\n"
    "    </script>"
    "    <table border=\"0\" style='font-family:\"monospace\"; font-size: 10px;'>\n"
    "     <caption style='font-family:Roboto; font-size:15px; text-align:left;'>Legend</caption>\n"
    "     <tr>\n"
    "        <th style=\"min-width:100px;\"><u>Kind</u></th>\n"
    "        <th style=\"width:35%;\"><u>Example</u></th>\n"
    "        <th style=\"width: 5%; min-width:50px;\"><u></u></th>\n"
    "        <th style=\"width:60%;\"><u>Description</u></th>\n"
    "     </tr>\n"
    "      <tr class='normal1'>"
            "<td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>"
            "<td>v1 = load32 Ptr1</td>"
            "<td><button id='normal' onclick=\"toggle(this, 'normal')\">Hide</button></td>"
            "<td>A regular SkVM command</td></tr>\n"
    "      <tr class='normal1 origin1'><td>*{N}</td>"
            "<td>v9 = gt_f32 v0, v1</td>"
            "<td><button id='dead' onclick=\"toggle(this, 'deduped')\">Hide</button></td>"
            "<td>A {N} times deduped SkVM command</td></tr>\n"
    "      <tr class='normal1'><td>&#8593;&#8593;&#8593; &nbsp;&nbsp;&nbsp;</td>"
            "<td>v22 = splat 3f800000 (1)</td><td></td>"
            "<td>A hoisted SkVM command</td></tr>\n"
    "      <tr class='source1'><td class='mask'>mask&#8618;v{N}(-1)</td>"
            "<td>// C++ source line</td><td></td>"
            "<td>Enter into the procedure with mask v{N} (which has a constant value -1)"
            "</td></tr>\n"
    "      <tr class='source1'><td class='mask'>mask&#8617;v{N}</td>"
            "<td>// C++ source line</td><td>"
            "</td><td>Exit the procedure with mask v{N}</td></tr>\n"
    "      <tr class='source1'><td class='mask'></td><td>// C++ source line</td>"
            "<td><button id='source' onclick=\"toggle(this, 'source')\">Hide</button></td>"
            "<td>Line trace back to C++ code</td></tr>\n"
    "      <tr class='dead1'><td></td><td>{dead code} = mul_f32 v1, v18</td>"
            "<td><button id='dead' onclick=\"toggle(this, 'dead')\">Hide</button></td>"
            "<td>An eliminated \"dead code\" SkVM command</td></tr>\n"
    "      <tr class='machine1'><td>{address}</td><td>vmovups (%rsi),%ymm0</td>"
            "<td><button id='machine' onclick=\"toggle(this, 'machine')\">Hide</button></td>"
            "<td>A disassembled machine command generated by SkVM command</td></tr>\n"
    "    </table>\n"
    "    <table border = \"0\"style='font-family:\"monospace\"; font-size: 10px;'>\n"
    "     <caption style='font-family:Roboto;font-size:15px;text-align:left;'>SkVM Code</caption>\n"
    "     <tr>\n"
    "        <th style=\"min-width:100px;\"><u>Kind</u></th>\n"
    "        <th style=\"width:40%;min-width:100px;\"><u>Command</u></th>\n"
    "        <th style=\"width:60%;\"><u>Comments</u></th>\n"
    "     </tr>");
}
void Visualizer::dumpTail() const {
    this->writeText(
    "      </table>\n"
            "</body>\n"
            "</html>"
    );
}
} // namespace skvm::viz
