/*
 * 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/sksl/tracing/SkSLDebugInfo.h"
#include "src/sksl/tracing/SkVMDebugTracePlayer.h"

#include <limits.h>
#include <algorithm>
#include <utility>

namespace SkSL {

void SkVMDebugTracePlayer::reset(sk_sp<SkVMDebugTrace> debugTrace) {
    size_t nslots = debugTrace ? debugTrace->fSlotInfo.size() : 0;
    fDebugTrace = debugTrace;
    fCursor = 0;
    fScope = 0;
    fSlots.clear();
    fSlots.resize(nslots, {/*fValue=*/0,
                           /*fScope=*/INT_MAX,
                           /*fWriteTime=*/0});
    fStack.clear();
    fStack.push_back({/*fFunction=*/-1,
                      /*fLine=*/-1,
                      /*fDisplayMask=*/SkBitSet(nslots)});
    fDirtyMask.emplace(nslots);
    fReturnValues.emplace(nslots);

    if (fDebugTrace) {
        for (size_t slotIdx = 0; slotIdx < nslots; ++slotIdx) {
            if (fDebugTrace->fSlotInfo[slotIdx].fnReturnValue >= 0) {
                fReturnValues->set(slotIdx);
            }
        }

        for (const SkVMTraceInfo& trace : fDebugTrace->fTraceInfo) {
            if (trace.op == SkVMTraceInfo::Op::kLine) {
                fLineNumbers[trace.data[0]] += 1;
            }
        }
    }
}

void SkVMDebugTracePlayer::step() {
    this->tidyState();
    while (!this->traceHasCompleted()) {
        if (this->execute(fCursor++)) {
            break;
        }
    }
}

void SkVMDebugTracePlayer::stepOver() {
    this->tidyState();
    size_t initialStackDepth = fStack.size();
    while (!this->traceHasCompleted()) {
        bool canEscapeFromThisStackDepth = (fStack.size() <= initialStackDepth);
        if (this->execute(fCursor++)) {
            if (canEscapeFromThisStackDepth || this->atBreakpoint()) {
                break;
            }
        }
    }
}

void SkVMDebugTracePlayer::stepOut() {
    this->tidyState();
    size_t initialStackDepth = fStack.size();
    while (!this->traceHasCompleted()) {
        if (this->execute(fCursor++)) {
            bool hasEscapedFromInitialStackDepth = (fStack.size() < initialStackDepth);
            if (hasEscapedFromInitialStackDepth || this->atBreakpoint()) {
                break;
            }
        }
    }
}

void SkVMDebugTracePlayer::run() {
    this->tidyState();
    while (!this->traceHasCompleted()) {
        if (this->execute(fCursor++)) {
            if (this->atBreakpoint()) {
                break;
            }
        }
    }
}

void SkVMDebugTracePlayer::tidyState() {
    fDirtyMask->reset();

    // Conceptually this is `fStack.back().fDisplayMask &= ~fReturnValues`, but SkBitSet doesn't
    // support masking one set of bits against another.
    fReturnValues->forEachSetIndex([&](int slot) {
        fStack.back().fDisplayMask.reset(slot);
    });
}

bool SkVMDebugTracePlayer::traceHasCompleted() const {
    return !fDebugTrace || fCursor >= fDebugTrace->fTraceInfo.size();
}

int32_t SkVMDebugTracePlayer::getCurrentLine() const {
    SkASSERT(!fStack.empty());
    return fStack.back().fLine;
}

int32_t SkVMDebugTracePlayer::getCurrentLineInStackFrame(int stackFrameIndex) const {
    // The first entry on the stack is the "global" frame before we enter main, so offset our index
    // by one to account for it.
    ++stackFrameIndex;
    SkASSERT(stackFrameIndex > 0);
    SkASSERT((size_t)stackFrameIndex < fStack.size());
    return fStack[stackFrameIndex].fLine;
}

bool SkVMDebugTracePlayer::atBreakpoint() const {
    return fBreakpointLines.count(this->getCurrentLine());
}

void SkVMDebugTracePlayer::setBreakpoints(std::unordered_set<int> breakpointLines) {
    fBreakpointLines = std::move(breakpointLines);
}

void SkVMDebugTracePlayer::addBreakpoint(int line) {
    fBreakpointLines.insert(line);
}

void SkVMDebugTracePlayer::removeBreakpoint(int line) {
    fBreakpointLines.erase(line);
}

std::vector<int> SkVMDebugTracePlayer::getCallStack() const {
    SkASSERT(!fStack.empty());
    std::vector<int> funcs;
    funcs.reserve(fStack.size() - 1);
    for (size_t index = 1; index < fStack.size(); ++index) {
        funcs.push_back(fStack[index].fFunction);
    }
    return funcs;
}

int SkVMDebugTracePlayer::getStackDepth() const {
    SkASSERT(!fStack.empty());
    return fStack.size() - 1;
}

std::vector<SkVMDebugTracePlayer::VariableData> SkVMDebugTracePlayer::getVariablesForDisplayMask(
        const SkBitSet& displayMask) const {
    SkASSERT(displayMask.size() == fSlots.size());

    std::vector<VariableData> vars;
    displayMask.forEachSetIndex([&](int slot) {
        double typedValue = fDebugTrace->interpretValueBits(slot, fSlots[slot].fValue);
        vars.push_back({slot, fDirtyMask->test(slot), typedValue});
    });
    // Order the variable list so that the most recently-written variables are shown at the top.
    std::stable_sort(vars.begin(), vars.end(), [&](const VariableData& a, const VariableData& b) {
        return fSlots[a.fSlotIndex].fWriteTime > fSlots[b.fSlotIndex].fWriteTime;
    });
    return vars;
}

std::vector<SkVMDebugTracePlayer::VariableData> SkVMDebugTracePlayer::getLocalVariables(
        int stackFrameIndex) const {
    // The first entry on the stack is the "global" frame before we enter main, so offset our index
    // by one to account for it.
    ++stackFrameIndex;
    if (stackFrameIndex <= 0 || (size_t)stackFrameIndex >= fStack.size()) {
        SkDEBUGFAILF("stack frame %d doesn't exist", stackFrameIndex - 1);
        return {};
    }
    return this->getVariablesForDisplayMask(fStack[stackFrameIndex].fDisplayMask);
}

std::vector<SkVMDebugTracePlayer::VariableData> SkVMDebugTracePlayer::getGlobalVariables() const {
    if (fStack.empty()) {
        return {};
    }
    return this->getVariablesForDisplayMask(fStack.front().fDisplayMask);
}

void SkVMDebugTracePlayer::updateVariableWriteTime(int slotIdx, size_t cursor) {
    // The slotIdx could point to any slot within a variable.
    // We want to update the write time on EVERY slot associated with this variable.
    // The SlotInfo's groupIndex gives us enough information to find the affected range.
    const SkSL::SlotDebugInfo& changedSlot = fDebugTrace->fSlotInfo[slotIdx];
    slotIdx -= changedSlot.groupIndex;
    SkASSERT(slotIdx >= 0);
    SkASSERT(slotIdx < (int)fDebugTrace->fSlotInfo.size());

    for (;;) {
        fSlots[slotIdx++].fWriteTime = cursor;

        // Stop if we've reached the final slot.
        if (slotIdx >= (int)fDebugTrace->fSlotInfo.size()) {
            break;
        }
        // Each separate variable-group starts with a groupIndex of 0; stop when we detect this.
        if (fDebugTrace->fSlotInfo[slotIdx].groupIndex == 0) {
            break;
        }
    }
}

bool SkVMDebugTracePlayer::execute(size_t position) {
    if (position >= fDebugTrace->fTraceInfo.size()) {
        SkDEBUGFAILF("position %zu out of range", position);
        return true;
    }

    const SkVMTraceInfo& trace = fDebugTrace->fTraceInfo[position];
    switch (trace.op) {
        case SkVMTraceInfo::Op::kLine: { // data: line number, (unused)
            SkASSERT(!fStack.empty());
            int lineNumber = trace.data[0];
            SkASSERT(lineNumber >= 0);
            SkASSERT((size_t)lineNumber < fDebugTrace->fSource.size());
            SkASSERT(fLineNumbers[lineNumber] > 0);
            fStack.back().fLine = lineNumber;
            fLineNumbers[lineNumber] -= 1;
            return true;
        }
        case SkVMTraceInfo::Op::kVar: {  // data: slot, value
            int slotIdx = trace.data[0];
            int value = trace.data[1];
            SkASSERT(slotIdx >= 0);
            SkASSERT((size_t)slotIdx < fDebugTrace->fSlotInfo.size());
            fSlots[slotIdx].fValue = value;
            fSlots[slotIdx].fScope = std::min<>(fSlots[slotIdx].fScope, fScope);
            this->updateVariableWriteTime(slotIdx, position);
            if (fDebugTrace->fSlotInfo[slotIdx].fnReturnValue < 0) {
                // Normal variables are associated with the current function.
                SkASSERT(fStack.size() > 0);
                fStack.rbegin()[0].fDisplayMask.set(slotIdx);
            } else {
                // Return values are associated with the parent function (since the current function
                // is exiting and we won't see them there).
                SkASSERT(fStack.size() > 1);
                fStack.rbegin()[1].fDisplayMask.set(slotIdx);
            }
            fDirtyMask->set(slotIdx);
            break;
        }
        case SkVMTraceInfo::Op::kEnter: { // data: function index, (unused)
            int fnIdx = trace.data[0];
            SkASSERT(fnIdx >= 0);
            SkASSERT((size_t)fnIdx < fDebugTrace->fFuncInfo.size());
            fStack.push_back({/*fFunction=*/fnIdx,
                              /*fLine=*/-1,
                              /*fDisplayMask=*/SkBitSet(fDebugTrace->fSlotInfo.size())});
            break;
        }
        case SkVMTraceInfo::Op::kExit: { // data: function index, (unused)
            SkASSERT(!fStack.empty());
            SkASSERT(fStack.back().fFunction == trace.data[0]);
            fStack.pop_back();
            return true;
        }
        case SkVMTraceInfo::Op::kScope: { // data: scope delta, (unused)
            SkASSERT(!fStack.empty());
            fScope += trace.data[0];
            if (trace.data[0] < 0) {
                // If the scope is being reduced, discard variables that are now out of scope.
                for (size_t slotIdx = 0; slotIdx < fSlots.size(); ++slotIdx) {
                    if (fScope < fSlots[slotIdx].fScope) {
                        fSlots[slotIdx].fScope = INT_MAX;
                        fStack.back().fDisplayMask.reset(slotIdx);
                    }
                }
            }
            return false;
        }
    }

    return false;
}

}  // namespace SkSL
