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

#ifndef SKSL_COMPILER
#define SKSL_COMPILER

#include <set>
#include <unordered_set>
#include <vector>
#include "src/sksl/SkSLASTFile.h"
#include "src/sksl/SkSLAnalysis.h"
#include "src/sksl/SkSLContext.h"
#include "src/sksl/SkSLErrorReporter.h"
#include "src/sksl/SkSLInliner.h"
#include "src/sksl/SkSLParsedModule.h"
#include "src/sksl/ir/SkSLProgram.h"
#include "src/sksl/ir/SkSLSymbolTable.h"

#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
#include "src/gpu/GrShaderVar.h"
#endif

#define SK_FRAGCOLOR_BUILTIN           10001
#define SK_IN_BUILTIN                  10002
#define SK_OUT_BUILTIN                 10007
#define SK_LASTFRAGCOLOR_BUILTIN       10008
#define SK_MAIN_COORDS_BUILTIN         10009
#define SK_INPUT_COLOR_BUILTIN         10010
#define SK_DEST_COLOR_BUILTIN          10011
#define SK_FRAGCOORD_BUILTIN              15
#define SK_CLOCKWISE_BUILTIN              17
#define SK_VERTEXID_BUILTIN               42
#define SK_INSTANCEID_BUILTIN             43
#define SK_INVOCATIONID_BUILTIN            8
#define SK_POSITION_BUILTIN                0

class SkBitSet;
class SkSLCompileBench;

namespace SkSL {

namespace dsl {
    class DSLCore;
    class DSLWriter;
}

class ExternalFunction;
class FunctionDeclaration;
class IRGenerator;
class IRIntrinsicMap;
class ProgramUsage;

struct LoadedModule {
    ProgramKind                                  fKind;
    std::shared_ptr<SymbolTable>                 fSymbols;
    std::vector<std::unique_ptr<ProgramElement>> fElements;
};

/**
 * Main compiler entry point. This is a traditional compiler design which first parses the .sksl
 * file into an abstract syntax tree (a tree of ASTNodes), then performs semantic analysis to
 * produce a Program (a tree of IRNodes), then feeds the Program into a CodeGenerator to produce
 * compiled output.
 *
 * See the README for information about SkSL.
 */
class SK_API Compiler : public ErrorReporter {
public:
    static constexpr const char FRAGCOLOR_NAME[] = "sk_FragColor";
    static constexpr const char RTADJUST_NAME[]  = "sk_RTAdjust";
    static constexpr const char PERVERTEX_NAME[] = "sk_PerVertex";
    static constexpr const char POISON_TAG[]     = "<POISON>";

    /**
     * Gets a float4 that adjusts the position from Skia device coords to normalized device coords,
     * used to populate sk_RTAdjust.  Assuming the transformed position, pos, is a homogeneous
     * float4, the vec, v, is applied as such:
     * float4((pos.xy * v.xz) + sk_Position.ww * v.yw, 0, pos.w);
     */
    static std::array<float, 4> GetRTAdjustVector(SkISize rtDims, bool flipY) {
        std::array<float, 4> result;
        result[0] = 2.f/rtDims.width();
        result[2] = 2.f/rtDims.height();
        result[1] = -1.f;
        result[3] = -1.f;
        if (flipY) {
            result[2] = -result[2];
            result[3] = -result[3];
        }
        return result;
    }

    /**
     * Uniform values  by the compiler to implement origin-neutral dFdy, sk_Clockwise, and
     * sk_FragCoord.
     */
    static std::array<float, 2> GetRTFlipVector(int rtHeight, bool flipY) {
        std::array<float, 2> result;
        result[0] = flipY ? rtHeight : 0.f;
        result[1] = flipY ?     -1.f : 1.f;
        return result;
    }

    struct OptimizationContext {
        // nodes we have already reported errors for and should not error on again
        std::unordered_set<const IRNode*> fSilences;
        // true if we have updated the CFG during this pass
        bool fUpdated = false;
        // true if we need to completely regenerate the CFG
        bool fNeedsRescan = false;
        // Metadata about function and variable usage within the program
        ProgramUsage* fUsage = nullptr;
        // Nodes which we can't throw away until the end of optimization
        StatementArray fOwnedStatements;
    };

    Compiler(const ShaderCapsClass* caps);

    ~Compiler() override;

    Compiler(const Compiler&) = delete;
    Compiler& operator=(const Compiler&) = delete;

    /**
     * Allows optimization settings to be unilaterally overridden. This is meant to allow tools like
     * Viewer or Nanobench to override the compiler's ProgramSettings and ShaderCaps for debugging.
     */
    enum class OverrideFlag {
        kDefault,
        kOff,
        kOn,
    };
    static void EnableOptimizer(OverrideFlag flag) { sOptimizer = flag; }
    static void EnableInliner(OverrideFlag flag) { sInliner = flag; }

    /**
     * If fExternalFunctions is supplied in the settings, those values are registered in the symbol
     * table of the Program, but ownership is *not* transferred. It is up to the caller to keep them
     * alive.
     */
    std::unique_ptr<Program> convertProgram(
            ProgramKind kind,
            String text,
            Program::Settings settings);

    bool toSPIRV(Program& program, OutputStream& out);

    bool toSPIRV(Program& program, String* out);

    bool toGLSL(Program& program, OutputStream& out);

    bool toGLSL(Program& program, String* out);

    bool toHLSL(Program& program, String* out);

    bool toMetal(Program& program, OutputStream& out);

    bool toMetal(Program& program, String* out);

    void error(int offset, String msg) override;

    String errorText(bool showCount = true);

    void writeErrorCount();

    int errorCount() override {
        return fErrorCount;
    }

    void setErrorCount(int c) override;

    Context& context() {
        return *fContext;
    }

    // When  SKSL_STANDALONE, fPath is used. (fData, fSize) will be (nullptr, 0)
    // When !SKSL_STANDALONE, fData and fSize are used. fPath will be nullptr.
    struct ModuleData {
        const char*    fPath;

        const uint8_t* fData;
        size_t         fSize;
    };

    static ModuleData MakeModulePath(const char* path) {
        return ModuleData{path, /*fData=*/nullptr, /*fSize=*/0};
    }
    static ModuleData MakeModuleData(const uint8_t* data, size_t size) {
        return ModuleData{/*fPath=*/nullptr, data, size};
    }

    LoadedModule loadModule(ProgramKind kind, ModuleData data, std::shared_ptr<SymbolTable> base,
                            bool dehydrate);
    ParsedModule parseModule(ProgramKind kind, ModuleData data, const ParsedModule& base);

    IRGenerator& irGenerator() {
        return *fIRGenerator;
    }

    const ParsedModule& moduleForProgramKind(ProgramKind kind);

private:
    const ParsedModule& loadGPUModule();
    const ParsedModule& loadFragmentModule();
    const ParsedModule& loadVertexModule();
    const ParsedModule& loadGeometryModule();
    const ParsedModule& loadPublicModule();
    const ParsedModule& loadRuntimeColorFilterModule();
    const ParsedModule& loadRuntimeShaderModule();
    const ParsedModule& loadRuntimeBlenderModule();

    /** Verifies that @if and @switch statements were actually optimized away. */
    void verifyStaticTests(const Program& program);

    /** Optimize every function in the program. */
    bool optimize(Program& program);

    /** Optimize the module. */
    bool optimize(LoadedModule& module);

    /** Eliminates unused functions from a Program, according to the stats in ProgramUsage. */
    bool removeDeadFunctions(Program& program, ProgramUsage* usage);

    /** Eliminates unreferenced variables from a Program, according to the stats in ProgramUsage. */
    bool removeDeadGlobalVariables(Program& program, ProgramUsage* usage);
    bool removeDeadLocalVariables(Program& program, ProgramUsage* usage);

    /** Eliminates unreachable statements from a Program. */
    void removeUnreachableCode(Program& program, ProgramUsage* usage);

    Position position(int offset);

    std::shared_ptr<Context> fContext;

    std::shared_ptr<SymbolTable> fRootSymbolTable;
    std::shared_ptr<SymbolTable> fPrivateSymbolTable;

    ParsedModule fRootModule;                // Core types

    ParsedModule fPrivateModule;             // [Root] + Internal types
    ParsedModule fGPUModule;                 // [Private] + GPU intrinsics, helper functions
    ParsedModule fVertexModule;              // [GPU] + Vertex stage decls
    ParsedModule fFragmentModule;            // [GPU] + Fragment stage decls
    ParsedModule fGeometryModule;            // [GPU] + Geometry stage decls

    ParsedModule fPublicModule;              // [Root] + Public features
    ParsedModule fRuntimeColorFilterModule;  // [Public] + Runtime shader decls
    ParsedModule fRuntimeShaderModule;       // [Public] + Runtime color filter decls
    ParsedModule fRuntimeBlenderModule;      // [Public] + Runtime blender decls

    // holds ModifiersPools belonging to the core includes for lifetime purposes
    ModifiersPool fCoreModifiers;

    Inliner fInliner;
    std::unique_ptr<IRGenerator> fIRGenerator;

    const String* fSource = nullptr;
    int fErrorCount = 0;
    String fErrorText;
    std::vector<size_t> fErrorTextLength;

    static OverrideFlag sOptimizer;
    static OverrideFlag sInliner;

    friend class AutoSource;
    friend class ::SkSLCompileBench;
    friend class dsl::DSLCore;
    friend class dsl::DSLWriter;
};

}  // namespace SkSL

#endif
