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

#ifndef SKSL_REHYDRATOR
#define SKSL_REHYDRATOR

#include "src/sksl/SkSLDefines.h"

#include "src/sksl/ir/SkSLModifiers.h"
#include "src/sksl/ir/SkSLSymbol.h"

#include <vector>

namespace SkSL {

class Context;
class ErrorReporter;
struct Expression;
struct ProgramElement;
struct Statement;
class SymbolTable;
class Type;

union FloatIntUnion {
    float   fFloat;
    int32_t fInt;
};

/**
 * Interprets a simple bytecode format that encodes the structure of an SkSL IR tree. This is used
 * to process the .sksl files representing SkSL's core include files, so that they can be quickly
 * reconstituted at runtime.
 */
class Rehydrator {
public:
    enum Command {
        // uint16 id, Type componentType, uint8 count
        kArrayType_Command,
        // Expression left, uint8 op, Expression right, Type type
        kBinary_Command,
        // SymbolTable symbolTable, uint8 statementCount, Statement[] statements, bool isScope
        kBlock_Command,
        // bool value
        kBoolLiteral_Command,
        kBreak_Command,
        // int16 builtin
        kBuiltinLayout_Command,
        // Type type, uint8 argCount, Expression[] arguments
        kConstructor_Command,
        kContinue_Command,
        kDefaultLayout_Command,
        kDefaultModifiers_Command,
        kDiscard_Command,
        // Statement stmt, Expression test
        kDo_Command,
        // uint8 count, uint8 index
        kElements_Command,
        // String typeName, SymbolTable symbols, int32[] values
        kEnum_Command,
        // uint16 id, String name
        kEnumType_Command,
        // Expression expression
        kExpressionStatement_Command,
        // uint16 ownerId, uint8 index
        kField_Command,
        // Expression base, uint8 index, uint8 ownerKind
        kFieldAccess_Command,
        // float value
        kFloatLiteral_Command,
        // Statement initializer, Expression test, Expression next, Statement body,
        // SymbolTable symbols
        kFor_Command,
        // Type type, uint16 function, uint8 argCount, Expression[] arguments
        kFunctionCall_Command,
        // uint16 declaration, Statement body, uint8 refCount, uint16[] referencedIntrinsics
        kFunctionDefinition_Command,
        // uint16 id, Modifiers modifiers, String name, uint8 parameterCount, uint16[] parameterIds,
        // Type returnType
        kFunctionDeclaration_Command,
        // bool isStatic, Expression test, Statement ifTrue, Statement ifFalse
        kIf_Command,
        // Expression base, Expression index
        kIndex_Command,
        // Variable* var, String typeName, String instanceName, uint8 sizeCount, Expression[] sizes
        kInterfaceBlock_Command,
        // int32 value
        kIntLiteral_Command,
        // int32 flags, int8 location, int8 offset, int8 binding, int8 index, int8 set,
        // int16 builtin, int8 inputAttachmentIndex, int8 format, int8 primitive, int8 maxVertices,
        // int8 invocations, String marker, String when, int8 key, int8 ctype
        kLayout_Command,
        // Layout layout, uint8 flags
        kModifiers8Bit_Command,
        // Layout layout, uint32 flags
        kModifiers_Command,
        // uint16 id, Type baseType
        kNullableType_Command,
        kNullLiteral_Command,
        // uint8 op, Expression operand
        kPostfix_Command,
        // uint8 op, Expression operand
        kPrefix_Command,
        // Expression value
        kReturn_Command,
        // String name, Expression value
        kSetting_Command,
        // uint16 id, String name, uint8 fieldCount, (Modifiers, String, Type)[] fields
        kStructType_Command,
        // bool isStatic, SymbolTable symbols, Expression value, uint8 caseCount,
        // (Expression value, uint8 statementCount, Statement[] statements)[] cases
        kSwitch_Command,
        // Expression base, uint8 componentCount, uint8[] components
        kSwizzle_Command,
        // uint16 id
        kSymbolRef_Command,
        // uint16 owned symbol count, Symbol[] ownedSymbols, uint16 symbol count,
        // (String, uint16/*index*/)[].
        kSymbolTable_Command,
        // uint16 id, String name
        kSystemType_Command,
        // Expression test, Expression ifTrue, Expression ifFalse
        kTernary_Command,
        // uint16 id, FunctionDeclaration[] functions
        kUnresolvedFunction_Command,
        // uint16 id, Modifiers modifiers, String name, Type type, uint8 storage
        kVariable_Command,
        // uint16 varId, uint8 sizeCount, Expression[] sizes, Expression? value
        kVarDeclaration_Command,
        // Type baseType, uint8 varCount, VarDeclaration vars
        kVarDeclarations_Command,
        // uint16 varId, uint8 refKind
        kVariableReference_Command,
        kVoid_Command,
        // Expression test, Statement body
        kWhile_Command,
    };

    // src must remain in memory as long as the objects created from it do
    Rehydrator(Context* context, std::shared_ptr<SymbolTable> symbolTable,
               ErrorReporter* errorReporter, const uint8_t* src, size_t length)
        : fContext(*context)
        , fSymbolTable(std::move(symbolTable))
        , fStart(src)
        SkDEBUGCODE(, fEnd(fStart + length)) {
        SkASSERT(fSymbolTable);
        // skip past string data
        fIP = fStart;
        fIP += this->readU16();
    }

    std::vector<std::unique_ptr<ProgramElement>> elements();

    std::shared_ptr<SymbolTable> symbolTable();

private:
    int8_t readS8() {
        SkASSERT(fIP < fEnd);
        return *(fIP++);
    }

    uint8_t readU8() {
        return this->readS8();
    }

    int16_t readS16() {
        uint8_t b1 = this->readU8();
        uint8_t b2 = this->readU8();
        return (b2 << 8) + b1;
    }

    uint16_t readU16() {
        return this->readS16();
    }

    int32_t readS32() {
        uint8_t b1 = this->readU8();
        uint8_t b2 = this->readU8();
        uint8_t b3 = this->readU8();
        uint8_t b4 = this->readU8();
        return (b4 << 24) + (b3 << 16) + (b2 << 8) + b1;
    }

    uint32_t readU32() {
        return this->readS32();
    }

    StringFragment readString() {
        uint16_t offset = this->readU16();
        uint8_t length = *(uint8_t*) (fStart + offset);
        const char* chars = (const char*) fStart + offset + 1;
        return StringFragment(chars, length);
    }

    void addSymbol(int id, const Symbol* symbol) {
        while ((size_t) id >= fSymbols.size()) {
            fSymbols.push_back(nullptr);
        }
        fSymbols[id] = symbol;
    }

    template<typename T>
    T* symbolRef(Symbol::Kind kind) {
        uint16_t result = this->readU16();
        SkASSERT(fSymbols.size() > result);
        return (T*) fSymbols[result];
    }

    Layout layout();

    Modifiers modifiers();

    const Symbol* symbol();

    std::unique_ptr<ProgramElement> element();

    std::unique_ptr<Statement> statement();

    std::unique_ptr<Expression> expression();

    const Type* type();

    Context& fContext;
    std::shared_ptr<SymbolTable> fSymbolTable;
    std::vector<const Symbol*> fSymbols;

    const uint8_t* fStart;
    const uint8_t* fIP;
    SkDEBUGCODE(const uint8_t* fEnd;)

    friend class AutoRehydratorSymbolTable;
};

} // namespace

#endif
