//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

#include "compiler/translator/BuiltinsWorkaroundGLSL.h"

#include "angle_gl.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/Symbol.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/tree_util/BuiltIn.h"
#include "nb/cpp14oncpp11.h"

namespace sh
{

namespace
{
CONSTEXPR const ImmutableString kGlInstanceIDString("gl_InstanceID");
CONSTEXPR const ImmutableString kGlVertexIDString("gl_VertexID");

class TBuiltinsWorkaroundGLSL : public TIntermTraverser
{
  public:
    TBuiltinsWorkaroundGLSL(TSymbolTable *symbolTable, ShCompileOptions options);

    void visitSymbol(TIntermSymbol *node) override;
    bool visitDeclaration(Visit, TIntermDeclaration *node) override;

  private:
    void ensureVersionIsAtLeast(int version);

    ShCompileOptions mCompileOptions;

    bool isBaseInstanceDeclared = false;
    bool isBaseVertexDeclared   = false;
};

TBuiltinsWorkaroundGLSL::TBuiltinsWorkaroundGLSL(TSymbolTable *symbolTable,
                                                 ShCompileOptions options)
    : TIntermTraverser(true, false, false, symbolTable), mCompileOptions(options)
{}

void TBuiltinsWorkaroundGLSL::visitSymbol(TIntermSymbol *node)
{
    if (node->variable().symbolType() == SymbolType::BuiltIn)
    {
        if (node->getName() == kGlInstanceIDString)
        {
            TIntermSymbol *instanceIndexRef =
                new TIntermSymbol(BuiltInVariable::gl_InstanceIndex());

            if (isBaseInstanceDeclared)
            {
                TIntermSymbol *baseInstanceRef =
                    new TIntermSymbol(BuiltInVariable::angle_BaseInstance());

                TIntermBinary *subBaseInstance =
                    new TIntermBinary(EOpSub, instanceIndexRef, baseInstanceRef);
                queueReplacement(subBaseInstance, OriginalNode::IS_DROPPED);
            }
            else
            {
                queueReplacement(instanceIndexRef, OriginalNode::IS_DROPPED);
            }
        }
        else if (node->getName() == kGlVertexIDString)
        {
            TIntermSymbol *vertexIndexRef = new TIntermSymbol(BuiltInVariable::gl_VertexIndex());
            queueReplacement(vertexIndexRef, OriginalNode::IS_DROPPED);
        }
    }
}

bool TBuiltinsWorkaroundGLSL::visitDeclaration(Visit, TIntermDeclaration *node)
{
    const TIntermSequence &sequence = *(node->getSequence());
    ASSERT(!sequence.empty());

    for (TIntermNode *variableNode : sequence)
    {
        TIntermSymbol *variable = variableNode->getAsSymbolNode();
        if (variable && variable->variable().symbolType() == SymbolType::AngleInternal)
        {
            if (variable->getName() == "angle_BaseInstance")
            {
                isBaseInstanceDeclared = true;
            }
        }
    }
    return true;
}

}  // anonymous namespace

ANGLE_NO_DISCARD bool ShaderBuiltinsWorkaround(TCompiler *compiler,
                                               TIntermBlock *root,
                                               TSymbolTable *symbolTable,
                                               ShCompileOptions compileOptions)
{
    TBuiltinsWorkaroundGLSL builtins(symbolTable, compileOptions);
    root->traverse(&builtins);
    if (!builtins.updateTree(compiler, root))
    {
        return false;
    }
    return true;
}

}  // namespace sh
