/*
 * 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/SkVMDebugTrace.h"

#include "include/core/SkRefCnt.h"
#include "include/core/SkTypes.h"
#include "src/utils/SkBitSet.h"

#include <cstddef>
#include <cstdint>
#include <optional>
#include <unordered_map>
#include <unordered_set>
#include <vector>

namespace SkSL {

/**
 * Plays back a SkVM debug trace, allowing its contents to be viewed like a traditional debugger.
 */
class SkVMDebugTracePlayer {
public:
    /** Resets playback to the start of the trace. Breakpoints are not cleared. */
    void reset(sk_sp<SkVMDebugTrace> trace);

    /** Advances the simulation to the next Line op. */
    void step();

    /**
     * Advances the simulation to the next Line op, skipping past matched Enter/Exit pairs.
     * Breakpoints will also stop the simulation even if we haven't reached an Exit.
     */
    void stepOver();

    /**
     * Advances the simulation until we exit from the current stack frame.
     * Breakpoints will also stop the simulation even if we haven't left the stack frame.
     */
    void stepOut();

    /** Advances the simulation until we hit a breakpoint, or the trace completes. */
    void run();

    /** Breakpoints will force the simulation to stop whenever a desired line is reached. */
    void setBreakpoints(std::unordered_set<int> breakpointLines);
    void addBreakpoint(int line);
    void removeBreakpoint(int line);
    using BreakpointSet = std::unordered_set<int>;
    const BreakpointSet& getBreakpoints() { return fBreakpointLines; }

    /** Returns true if we have reached the end of the trace. */
    bool traceHasCompleted() const;

    /** Returns true if there is a breakpoint set at the current line. */
    bool atBreakpoint() const;

    /** Retrieves the cursor position. */
    size_t cursor() { return fCursor; }

    /** Retrieves the current line. */
    int32_t getCurrentLine() const;

    /** Retrieves the current line for a given stack frame. */
    int32_t getCurrentLineInStackFrame(int stackFrameIndex) const;

    /** Returns the call stack as an array of FunctionInfo indices. */
    std::vector<int> getCallStack() const;

    /** Returns the size of the call stack. */
    int getStackDepth() const;

    /**
     * Returns every line number reached inside this debug trace, along with the remaining number of
     * times that this trace will reach it. e.g. {100, 2} means line 100 will be reached twice.
     */
    using LineNumberMap = std::unordered_map<int, int>;
    const LineNumberMap& getLineNumbersReached() const { return fLineNumbers; }

    /** Returns variables from a stack frame, or from global scope. */
    struct VariableData {
        int     fSlotIndex;
        bool    fDirty;  // has this slot been written-to since the last step call?
        double  fValue;  // value in slot (with type-conversion applied)
    };
    std::vector<VariableData> getLocalVariables(int stackFrameIndex) const;
    std::vector<VariableData> getGlobalVariables() const;

private:
    /**
     * Executes the trace op at the passed-in cursor position. Returns true if we've reached a line
     * or exit trace op, which indicate a stopping point.
     */
    bool execute(size_t position);

    /**
     * Cleans up temporary state between steps, such as the dirty mask and function return values.
     */
    void tidyState();

    /** Updates fWriteTime for the entire variable at a given slot. */
    void updateVariableWriteTime(int slotIdx, size_t writeTime);

    /** Returns a vector of the indices and values of each slot that is enabled in `bits`. */
    std::vector<VariableData> getVariablesForDisplayMask(const SkBitSet& bits) const;

    struct StackFrame {
        int32_t   fFunction;     // from fFuncInfo
        int32_t   fLine;         // our current line number within the function
        SkBitSet  fDisplayMask;  // the variable slots which have been touched in this function
    };
    struct Slot {
        int32_t   fValue;        // values in each slot
        int       fScope;        // the scope value of each slot
        size_t    fWriteTime;    // when was the variable in this slot most recently written?
                                 // (by cursor position)
    };
    sk_sp<SkVMDebugTrace>      fDebugTrace;
    size_t                     fCursor = 0;      // position of the read head
    int                        fScope = 0;       // the current scope depth (as tracked by
                                                 // trace_scope)
    std::vector<Slot>          fSlots;           // the array of all slots
    std::vector<StackFrame>    fStack;           // the execution stack
    std::optional<SkBitSet>    fDirtyMask;       // variable slots touched during the most-recently
                                                 // executed step
    std::optional<SkBitSet>    fReturnValues;    // variable slots containing return values
    LineNumberMap              fLineNumbers;     // holds [line number, the remaining number of
                                                 // times to reach this line during the trace]
    BreakpointSet              fBreakpointLines; // all breakpoints set by setBreakpointLines
};

}  // namespace SkSL
