/*
 * 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 "tools/viewer/SkSLDebuggerSlide.h"

#include "include/core/SkCanvas.h"
#include "include/core/SkStream.h"
#include "tools/viewer/Viewer.h"

#include <algorithm>
#include <cstdio>
#include "imgui.h"

using namespace sk_app;
using LineNumberMap = SkSL::SkVMDebugTracePlayer::LineNumberMap;

///////////////////////////////////////////////////////////////////////////////

SkSLDebuggerSlide::SkSLDebuggerSlide() {
    fName = "Debugger";
    fTrace = sk_make_sp<SkSL::SkVMDebugTrace>();
}

void SkSLDebuggerSlide::load(SkScalar winWidth, SkScalar winHeight) {}

void SkSLDebuggerSlide::unload() {
    fTrace = sk_make_sp<SkSL::SkVMDebugTrace>();
    fPlayer.reset(nullptr);
    fPlayer.setBreakpoints(std::unordered_set<int>{});
}

void SkSLDebuggerSlide::showLoadTraceGUI() {
    ImGui::InputText("Trace Path", fTraceFile, std::size(fTraceFile));
    bool load = ImGui::Button("Load Debug Trace");

    if (load) {
        SkFILEStream file(fTraceFile);
        if (!file.isValid()) {
            ImGui::OpenPopup("Can't Open Trace");
        } else if (!fTrace->readTrace(&file)) {
            ImGui::OpenPopup("Invalid Trace");
        } else {
            // Trace loaded successfully. On the next refresh, the user will see the debug UI.
            fPlayer.reset(fTrace);
            fPlayer.step();
            fRefresh = true;
            return;
        }
    }

    if (ImGui::BeginPopupModal("Can't Open Trace", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
        ImGui::Text("The trace file doesn't exist.");
        ImGui::Separator();
        if (ImGui::Button("OK", ImVec2(120, 0))) {
            ImGui::CloseCurrentPopup();
        }
        ImGui::EndPopup();
    }

    if (ImGui::BeginPopupModal("Invalid Trace", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
        ImGui::Text("The trace data could not be parsed.");
        ImGui::Separator();
        if (ImGui::Button("OK", ImVec2(120, 0))) {
            ImGui::CloseCurrentPopup();
        }
        ImGui::EndPopup();
    }
}

void SkSLDebuggerSlide::showDebuggerGUI() {
    if (ImGui::Button("Reset")) {
        fPlayer.reset(fTrace);
        fRefresh = true;
    }
    ImGui::SameLine(/*offset_from_start_x=*/0, /*spacing=*/100);
    if (ImGui::Button("Step")) {
        fPlayer.step();
        fRefresh = true;
    }
    ImGui::SameLine();
    if (ImGui::Button("Step Over")) {
        fPlayer.stepOver();
        fRefresh = true;
    }
    ImGui::SameLine();
    if (ImGui::Button("Step Out")) {
        fPlayer.stepOut();
        fRefresh = true;
    }
    ImGui::SameLine(/*offset_from_start_x=*/0, /*spacing=*/100);
    if (ImGui::Button(fPlayer.getBreakpoints().empty() ? "Run" : "Run to Breakpoint")) {
        fPlayer.run();
        fRefresh = true;
    }

    this->showStackTraceTable();
    this->showVariableTable();
    this->showCodeTable();
}

void SkSLDebuggerSlide::showCodeTable() {
    constexpr ImGuiTableFlags kTableFlags =
            ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter |
            ImGuiTableFlags_BordersV;
    constexpr ImGuiTableColumnFlags kColumnFlags =
            ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_NoReorder |
            ImGuiTableColumnFlags_NoHide | ImGuiTableColumnFlags_NoSort |
            ImGuiTableColumnFlags_NoHeaderLabel;

    ImVec2 contentRect = ImGui::GetContentRegionAvail();
    ImVec2 codeViewSize = ImVec2(0.0f, contentRect.y);
    if (ImGui::BeginTable("Code View", /*column=*/2, kTableFlags, codeViewSize)) {
        ImGui::TableSetupColumn("", kColumnFlags | ImGuiTableColumnFlags_WidthFixed);
        ImGui::TableSetupColumn("Code", kColumnFlags | ImGuiTableColumnFlags_WidthStretch);

        ImGuiListClipper clipper;
        clipper.Begin(fTrace->fSource.size());
        while (clipper.Step()) {
            for (int row = clipper.DisplayStart; row < clipper.DisplayEnd; row++) {
                size_t humanReadableLine = row + 1;

                ImGui::TableNextRow();
                if (fPlayer.getCurrentLine() == (int)humanReadableLine) {
                    ImGui::TableSetBgColor(
                            ImGuiTableBgTarget_RowBg1,
                            ImGui::GetColorU32(ImGui::GetStyleColorVec4(ImGuiCol_TextSelectedBg)));
                }

                // Show line numbers and breakpoints.
                ImGui::TableSetColumnIndex(0);
                const LineNumberMap& lineNumberMap = fPlayer.getLineNumbersReached();
                LineNumberMap::const_iterator iter = lineNumberMap.find(humanReadableLine);
                bool reachable = iter != lineNumberMap.end() && iter->second > 0;
                bool breakpointOn = fPlayer.getBreakpoints().count(humanReadableLine);
                if (breakpointOn) {
                    ImGui::PushStyleColor(ImGuiCol_Text,          ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
                    ImGui::PushStyleColor(ImGuiCol_Button,        ImVec4(1.0f, 0.0f, 0.0f, 0.70f));
                    ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.0f, 0.0f, 0.0f, 0.85f));
                    ImGui::PushStyleColor(ImGuiCol_ButtonActive,  ImVec4(1.0f, 0.0f, 0.0f, 1.0f));
                } else if (reachable) {
                    ImGui::PushStyleColor(ImGuiCol_Text,          ImVec4(1.0f, 1.0f, 1.0f, 0.75f));
                    ImGui::PushStyleColor(ImGuiCol_Button,        ImVec4(1.0f, 1.0f, 1.0f, 0.0f));
                    ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.0f, 1.0f, 1.0f, 0.2f));
                    ImGui::PushStyleColor(ImGuiCol_ButtonActive,  ImVec4(1.0f, 1.0f, 1.0f, 0.4f));
                } else {
                    ImGui::PushStyleColor(ImGuiCol_Text,          ImVec4(1.0f, 1.0f, 1.0f, 0.25f));
                    ImGui::PushStyleColor(ImGuiCol_Button,        ImVec4(1.0f, 1.0f, 1.0f, 0.0f));
                    ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.0f, 1.0f, 1.0f, 0.0f));
                    ImGui::PushStyleColor(ImGuiCol_ButtonActive,  ImVec4(1.0f, 1.0f, 1.0f, 0.0f));
                }
                if (ImGui::SmallButton(SkStringPrintf("%03zu ", humanReadableLine).c_str())) {
                    if (breakpointOn) {
                        fPlayer.removeBreakpoint(humanReadableLine);
                    } else if (reachable) {
                        fPlayer.addBreakpoint(humanReadableLine);
                    }
                }
                ImGui::PopStyleColor(4);

                // Show lines of code.
                ImGui::TableSetColumnIndex(1);
                ImGui::Text("%s", fTrace->fSource[row].c_str());
            }
        }

        if (fRefresh) {
            int linesVisible = contentRect.y / ImGui::GetTextLineHeightWithSpacing();
            int centerLine = (fPlayer.getCurrentLine() - 1) - (linesVisible / 2);
            centerLine = std::max(0, centerLine);
            ImGui::SetScrollY(clipper.ItemsHeight * centerLine);
            fRefresh = false;
        }

        ImGui::EndTable();
    }
}

void SkSLDebuggerSlide::showStackTraceTable() {
    constexpr ImGuiTableFlags kTableFlags =
            ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter |
            ImGuiTableFlags_BordersV | ImGuiTableFlags_NoHostExtendX;
    constexpr ImGuiTableColumnFlags kColumnFlags =
            ImGuiTableColumnFlags_NoReorder | ImGuiTableColumnFlags_NoHide |
            ImGuiTableColumnFlags_NoSort;

    std::vector<int> callStack = fPlayer.getCallStack();

    ImVec2 contentRect = ImGui::GetContentRegionAvail();
    ImVec2 stackViewSize = ImVec2(contentRect.x / 3.0f,
                                  ImGui::GetTextLineHeightWithSpacing() * kNumTopRows);
    if (ImGui::BeginTable("Call Stack", /*column=*/1, kTableFlags, stackViewSize)) {
        ImGui::TableSetupColumn("Stack", kColumnFlags);
        ImGui::TableHeadersRow();

        ImGuiListClipper clipper;
        clipper.Begin(callStack.size());
        while (clipper.Step()) {
            for (int row = clipper.DisplayStart; row < clipper.DisplayEnd; row++) {
                int funcIdx = callStack.rbegin()[row];
                SkASSERT(funcIdx >= 0 && (size_t)funcIdx < fTrace->fFuncInfo.size());
                const SkSL::FunctionDebugInfo& funcInfo = fTrace->fFuncInfo[funcIdx];

                ImGui::TableNextRow();
                ImGui::TableSetColumnIndex(0);
                ImGui::Text("%s", funcInfo.name.c_str());
            }
        }
        ImGui::EndTable();
    }

    ImGui::SameLine();
}

void SkSLDebuggerSlide::showVariableTable() {
    constexpr ImGuiTableFlags kTableFlags =
            ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter |
            ImGuiTableFlags_BordersV | ImGuiTableFlags_Resizable;
    constexpr ImGuiTableColumnFlags kColumnFlags =
            ImGuiTableColumnFlags_NoReorder | ImGuiTableColumnFlags_NoHide |
            ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthStretch;

    int frame = fPlayer.getStackDepth() - 1;
    std::vector<SkSL::SkVMDebugTracePlayer::VariableData> vars;
    if (frame >= 0) {
        vars = fPlayer.getLocalVariables(frame);
    } else {
        vars = fPlayer.getGlobalVariables();
    }
    ImVec2 varViewSize = ImVec2(0.0f, ImGui::GetTextLineHeightWithSpacing() * kNumTopRows);
    if (ImGui::BeginTable("Variables", /*column=*/2, kTableFlags, varViewSize)) {
        ImGui::TableSetupColumn("Variable", kColumnFlags);
        ImGui::TableSetupColumn("Value", kColumnFlags);
        ImGui::TableHeadersRow();
        if (!vars.empty()) {
            ImGuiListClipper clipper;
            clipper.Begin(vars.size());
            while (clipper.Step()) {
                for (int row = clipper.DisplayStart; row < clipper.DisplayEnd; row++) {
                    const SkSL::SkVMDebugTracePlayer::VariableData& var = vars.at(row);
                    SkASSERT(var.fSlotIndex >= 0);
                    SkASSERT((size_t)var.fSlotIndex < fTrace->fSlotInfo.size());
                    const SkSL::SlotDebugInfo& slotInfo = fTrace->fSlotInfo[var.fSlotIndex];

                    ImGui::TableNextRow();
                    if (var.fDirty) {
                        // Highlight recently-changed variables.
                        ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg1,
                                               ImGui::GetColorU32(ImVec4{0.0f, 1.0f, 0.0f, 0.20f}));
                    }
                    ImGui::TableSetColumnIndex(0);
                    ImGui::Text("%s%s", slotInfo.name.c_str(),
                                        fTrace->getSlotComponentSuffix(var.fSlotIndex).c_str());
                    ImGui::TableSetColumnIndex(1);
                    ImGui::Text("%s",
                                fTrace->slotValueToString(var.fSlotIndex, var.fValue).c_str());
                }
            }
        }
        ImGui::EndTable();
    }
}

void SkSLDebuggerSlide::showRootGUI() {
    if (fTrace->fSource.empty()) {
        this->showLoadTraceGUI();
        return;
    }

    this->showDebuggerGUI();
}

void SkSLDebuggerSlide::draw(SkCanvas* canvas) {
    canvas->clear(SK_ColorWHITE);
    ImGui::Begin("Debugger", nullptr, ImGuiWindowFlags_AlwaysVerticalScrollbar);
    this->showRootGUI();
    ImGui::End();
}

bool SkSLDebuggerSlide::animate(double nanos) {
    return true;
}
