//
// Copyright 2016 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.
//

// UseInterfaceBlockFields.cpp: insert statements to reference all members in InterfaceBlock list at
// the beginning of main. This is to work around a Mac driver that treats unused standard/shared
// uniform blocks as inactive.

#include "compiler/translator/UseInterfaceBlockFields.h"

#include "compiler/translator/FindMain.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/util.h"

namespace sh
{

namespace
{

void AddFieldUseStatements(const ShaderVariable &var,
                           TIntermSequence *sequence,
                           const TSymbolTable &symbolTable)
{
    TString name = TString(var.name.c_str());
    if (var.isArray())
    {
        size_t pos = name.find_last_of('[');
        if (pos != TString::npos)
        {
            name = name.substr(0, pos);
        }
    }
    const TType *type;
    TType basicType;
    if (var.isStruct())
    {
        TVariable *structInfo = reinterpret_cast<TVariable *>(symbolTable.findGlobal(name));
        ASSERT(structInfo);
        const TType &structType = structInfo->getType();
        type                    = &structType;
    }
    else
    {
        basicType = sh::GetShaderVariableBasicType(var);
        type      = &basicType;
    }
    ASSERT(type);

    TIntermSymbol *symbol = new TIntermSymbol(0, name, *type);
    if (var.isArray())
    {
        for (unsigned int i = 0; i < var.arraySize; ++i)
        {
            TIntermBinary *element =
                new TIntermBinary(EOpIndexDirect, symbol, TIntermTyped::CreateIndexNode(i));
            sequence->insert(sequence->begin(), element);
        }
    }
    else
    {
        sequence->insert(sequence->begin(), symbol);
    }
}

void InsertUseCode(TIntermSequence *sequence,
                   const InterfaceBlockList &blocks,
                   const TSymbolTable &symbolTable)
{
    for (const auto &block : blocks)
    {
        if (block.instanceName.empty())
        {
            for (const auto &var : block.fields)
            {
                AddFieldUseStatements(var, sequence, symbolTable);
            }
        }
        else if (block.arraySize > 0)
        {
            TString name      = TString(block.instanceName.c_str());
            TVariable *ubInfo = reinterpret_cast<TVariable *>(symbolTable.findGlobal(name));
            ASSERT(ubInfo);
            TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, ubInfo->getType());
            for (unsigned int i = 0; i < block.arraySize; ++i)
            {
                TIntermBinary *instanceSymbol = new TIntermBinary(EOpIndexDirect, arraySymbol,
                                                                  TIntermTyped::CreateIndexNode(i));
                for (unsigned int j = 0; j < block.fields.size(); ++j)
                {
                    TIntermBinary *element =
                        new TIntermBinary(EOpIndexDirectInterfaceBlock, instanceSymbol,
                                          TIntermTyped::CreateIndexNode(j));
                    sequence->insert(sequence->begin(), element);
                }
            }
        }
        else
        {
            TString name      = TString(block.instanceName.c_str());
            TVariable *ubInfo = reinterpret_cast<TVariable *>(symbolTable.findGlobal(name));
            ASSERT(ubInfo);
            TIntermSymbol *blockSymbol = new TIntermSymbol(0, name, ubInfo->getType());
            for (unsigned int i = 0; i < block.fields.size(); ++i)
            {
                TIntermBinary *element = new TIntermBinary(
                    EOpIndexDirectInterfaceBlock, blockSymbol, TIntermTyped::CreateIndexNode(i));

                sequence->insert(sequence->begin(), element);
            }
        }
    }
}

}  // namespace anonymous

void UseInterfaceBlockFields(TIntermBlock *root,
                             const InterfaceBlockList &blocks,
                             const TSymbolTable &symbolTable)
{
    TIntermFunctionDefinition *main = FindMain(root);
    TIntermBlock *mainBody          = main->getBody();
    ASSERT(mainBody);
    InsertUseCode(mainBody->getSequence(), blocks, symbolTable);
}

}  // namespace sh
