/*
 * 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_PROGRAM
#define SKSL_PROGRAM

#include <vector>
#include <memory>

#include "src/sksl/ir/SkSLBoolLiteral.h"
#include "src/sksl/ir/SkSLExpression.h"
#include "src/sksl/ir/SkSLFloatLiteral.h"
#include "src/sksl/ir/SkSLIntLiteral.h"
#include "src/sksl/ir/SkSLModifiers.h"
#include "src/sksl/ir/SkSLProgramElement.h"
#include "src/sksl/ir/SkSLSymbolTable.h"

#ifdef SK_VULKAN
#include "src/gpu/vk/GrVkCaps.h"
#endif

// name of the render target width uniform
#define SKSL_RTWIDTH_NAME "u_skRTWidth"

// name of the render target height uniform
#define SKSL_RTHEIGHT_NAME "u_skRTHeight"

namespace SkSL {

class Context;

/**
 * Represents a fully-digested program, ready for code generation.
 */
struct Program {
    struct Settings {
        struct Value {
            Value(bool b)
            : fKind(kBool_Kind)
            , fValue(b) {}

            Value(int i)
            : fKind(kInt_Kind)
            , fValue(i) {}

            Value(unsigned int i)
            : fKind(kInt_Kind)
            , fValue(i) {}

            Value(float f)
            : fKind(kFloat_Kind)
            , fValueF(f) {}

            std::unique_ptr<Expression> literal(const Context& context, int offset) const {
                switch (fKind) {
                    case Program::Settings::Value::kBool_Kind:
                        return std::unique_ptr<Expression>(new BoolLiteral(context,
                                                                           offset,
                                                                           fValue));
                    case Program::Settings::Value::kInt_Kind:
                        return std::unique_ptr<Expression>(new IntLiteral(context,
                                                                          offset,
                                                                          fValue));
                    case Program::Settings::Value::kFloat_Kind:
                        return std::unique_ptr<Expression>(new FloatLiteral(context,
                                                                            offset,
                                                                            fValueF));
                    default:
                        SkASSERT(false);
                        return nullptr;
                }
            }

            enum {
                kBool_Kind,
                kInt_Kind,
                kFloat_Kind,
            } fKind;

            union {
                int   fValue;  // for kBool_Kind and kInt_Kind
                float fValueF; // for kFloat_Kind
            };
        };

#if defined(SKSL_STANDALONE) || !SK_SUPPORT_GPU
        const StandaloneShaderCaps* fCaps = &standaloneCaps;
#else
        const GrShaderCaps* fCaps = nullptr;
#endif
        // if false, sk_FragCoord is exactly the same as gl_FragCoord. If true, the y coordinate
        // must be flipped.
        bool fFlipY = false;
        // if false, sk_FragCoord is exactly the same as gl_FragCoord. If true, the w coordinate
        // must be inversed.
        bool fInverseW = false;
        // If true the destination fragment color is read sk_FragColor. It must be declared inout.
        bool fFragColorIsInOut = false;
        // if true, Setting objects (e.g. sk_Caps.fbFetchSupport) should be replaced with their
        // constant equivalents during compilation
        bool fReplaceSettings = true;
        // if true, all halfs are forced to be floats
        bool fForceHighPrecision = false;
        // if true, add -0.5 bias to LOD of all texture lookups
        bool fSharpenTextures = false;
        // if the program needs to create an RTHeight uniform, this is its offset in the uniform
        // buffer
        int fRTHeightOffset = -1;
        // if the program needs to create an RTHeight uniform and is creating spriv, this is the
        // binding and set number of the uniform buffer.
        int fRTHeightBinding = -1;
        int fRTHeightSet = -1;
        // If true, remove any uncalled functions other than main(). Note that a function which
        // starts out being used may end up being uncalled after optimization.
        bool fRemoveDeadFunctions = true;
    };

    struct Inputs {
        // if true, this program requires the render target width uniform to be defined
        bool fRTWidth;

        // if true, this program requires the render target height uniform to be defined
        bool fRTHeight;

        // if true, this program must be recompiled if the flipY setting changes. If false, the
        // program will compile to the same code regardless of the flipY setting.
        bool fFlipY;

        void reset() {
            fRTWidth = false;
            fRTHeight = false;
            fFlipY = false;
        }

        bool isEmpty() {
            return !fRTWidth && !fRTHeight && !fFlipY;
        }
    };

    class iterator {
    public:
        ProgramElement& operator*() {
            if (fIter1 != fEnd1) {
                return **fIter1;
            }
            return **fIter2;
        }

        iterator& operator++() {
            if (fIter1 != fEnd1) {
                ++fIter1;
                return *this;
            }
            ++fIter2;
            return *this;
        }

        bool operator==(const iterator& other) const {
            return fIter1 == other.fIter1 && fIter2 == other.fIter2;
        }

        bool operator!=(const iterator& other) const {
            return !(*this == other);
        }

    private:
        using inner = std::vector<std::unique_ptr<ProgramElement>>::iterator;

        iterator(inner begin1, inner end1, inner begin2, inner end2)
        : fIter1(begin1)
        , fEnd1(end1)
        , fIter2(begin2)
        , fEnd2(end2) {}

        inner fIter1;
        inner fEnd1;
        inner fIter2;
        inner fEnd2;

        friend struct Program;
    };

    class const_iterator {
    public:
        const ProgramElement& operator*() {
            if (fIter1 != fEnd1) {
                return **fIter1;
            }
            return **fIter2;
        }

        const_iterator& operator++() {
            if (fIter1 != fEnd1) {
                ++fIter1;
                return *this;
            }
            ++fIter2;
            return *this;
        }

        bool operator==(const const_iterator& other) const {
            return fIter1 == other.fIter1 && fIter2 == other.fIter2;
        }

        bool operator!=(const const_iterator& other) const {
            return !(*this == other);
        }

    private:
        using inner = std::vector<std::unique_ptr<ProgramElement>>::const_iterator;

        const_iterator(inner begin1, inner end1, inner begin2, inner end2)
        : fIter1(begin1)
        , fEnd1(end1)
        , fIter2(begin2)
        , fEnd2(end2) {}

        inner fIter1;
        inner fEnd1;
        inner fIter2;
        inner fEnd2;

        friend struct Program;
    };

    enum Kind {
        kFragment_Kind,
        kVertex_Kind,
        kGeometry_Kind,
        kFragmentProcessor_Kind,
        kPipelineStage_Kind,
        kGeneric_Kind,
    };

    Program(Kind kind,
            std::unique_ptr<String> source,
            Settings settings,
            std::shared_ptr<Context> context,
            std::vector<std::unique_ptr<ProgramElement>>* inheritedElements,
            std::vector<std::unique_ptr<ProgramElement>> elements,
            std::shared_ptr<SymbolTable> symbols,
            Inputs inputs)
    : fKind(kind)
    , fSource(std::move(source))
    , fSettings(settings)
    , fContext(context)
    , fSymbols(symbols)
    , fInputs(inputs)
    , fInheritedElements(inheritedElements)
    , fElements(std::move(elements)) {}

    iterator begin() {
        if (fInheritedElements) {
            return iterator(fInheritedElements->begin(), fInheritedElements->end(),
                            fElements.begin(), fElements.end());
        }
        return iterator(fElements.begin(), fElements.end(), fElements.end(), fElements.end());
    }

    iterator end() {
        if (fInheritedElements) {
            return iterator(fInheritedElements->end(), fInheritedElements->end(),
                            fElements.end(), fElements.end());
        }
        return iterator(fElements.end(), fElements.end(), fElements.end(), fElements.end());
    }

    const_iterator begin() const {
        if (fInheritedElements) {
            return const_iterator(fInheritedElements->begin(), fInheritedElements->end(),
                                  fElements.begin(), fElements.end());
        }
        return const_iterator(fElements.begin(), fElements.end(), fElements.end(), fElements.end());
    }

    const_iterator end() const {
        if (fInheritedElements) {
            return const_iterator(fInheritedElements->end(), fInheritedElements->end(),
                                  fElements.end(), fElements.end());
        }
        return const_iterator(fElements.end(), fElements.end(), fElements.end(), fElements.end());
    }

    Kind fKind;
    std::unique_ptr<String> fSource;
    Settings fSettings;
    std::shared_ptr<Context> fContext;
    // it's important to keep fElements defined after (and thus destroyed before) fSymbols,
    // because destroying elements can modify reference counts in symbols
    std::shared_ptr<SymbolTable> fSymbols;
    Inputs fInputs;
    bool fIsOptimized = false;

private:
    std::vector<std::unique_ptr<ProgramElement>>* fInheritedElements;
    std::vector<std::unique_ptr<ProgramElement>> fElements;

    friend class Compiler;
};

}  // namespace SkSL

#endif
