//
// Copyright (c) 2002-2011 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 "angle_gl.h"
#include "compiler/translator/BuiltInFunctionEmulator.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/Cache.h"

namespace sh
{

class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTraverser
{
  public:
    BuiltInFunctionEmulationMarker(BuiltInFunctionEmulator &emulator)
        : TIntermTraverser(true, false, false), mEmulator(emulator)
    {
    }

    bool visitUnary(Visit visit, TIntermUnary *node) override
    {
        if (visit == PreVisit)
        {
            bool needToEmulate =
                mEmulator.setFunctionCalled(node->getOp(), node->getOperand()->getType());
            if (needToEmulate)
                node->setUseEmulatedFunction();
        }
        return true;
    }

    bool visitAggregate(Visit visit, TIntermAggregate *node) override
    {
        if (visit == PreVisit)
        {
            // Here we handle all the built-in functions mapped to ops, not just the ones that are
            // currently identified as problematic.
            if (node->isConstructor() || node->isFunctionCall())
            {
                return true;
            }
            const TIntermSequence &sequence = *(node->getSequence());
            bool needToEmulate              = false;
            // Right now we only handle built-in functions with two or three parameters.
            if (sequence.size() == 2)
            {
                TIntermTyped *param1 = sequence[0]->getAsTyped();
                TIntermTyped *param2 = sequence[1]->getAsTyped();
                if (!param1 || !param2)
                    return true;
                needToEmulate = mEmulator.setFunctionCalled(node->getOp(), param1->getType(),
                                                            param2->getType());
            }
            else if (sequence.size() == 3)
            {
                TIntermTyped *param1 = sequence[0]->getAsTyped();
                TIntermTyped *param2 = sequence[1]->getAsTyped();
                TIntermTyped *param3 = sequence[2]->getAsTyped();
                if (!param1 || !param2 || !param3)
                    return true;
                needToEmulate = mEmulator.setFunctionCalled(node->getOp(), param1->getType(),
                                                            param2->getType(), param3->getType());
            }
            else if (sequence.size() == 4)
            {
                TIntermTyped *param1 = sequence[0]->getAsTyped();
                TIntermTyped *param2 = sequence[1]->getAsTyped();
                TIntermTyped *param3 = sequence[2]->getAsTyped();
                TIntermTyped *param4 = sequence[3]->getAsTyped();
                if (!param1 || !param2 || !param3 || !param4)
                    return true;
                needToEmulate =
                    mEmulator.setFunctionCalled(node->getOp(), param1->getType(), param2->getType(),
                                                param3->getType(), param4->getType());
            }
            else
            {
                return true;
            }

            if (needToEmulate)
                node->setUseEmulatedFunction();
        }
        return true;
    }

  private:
    BuiltInFunctionEmulator &mEmulator;
};

BuiltInFunctionEmulator::BuiltInFunctionEmulator()
{
}

BuiltInFunctionEmulator::FunctionId BuiltInFunctionEmulator::addEmulatedFunction(
    TOperator op,
    const TType *param,
    const char *emulatedFunctionDefinition)
{
    FunctionId id(op, param);
    mEmulatedFunctions[id] = std::string(emulatedFunctionDefinition);
    return id;
}

BuiltInFunctionEmulator::FunctionId BuiltInFunctionEmulator::addEmulatedFunction(
    TOperator op,
    const TType *param1,
    const TType *param2,
    const char *emulatedFunctionDefinition)
{
    FunctionId id(op, param1, param2);
    mEmulatedFunctions[id] = std::string(emulatedFunctionDefinition);
    return id;
}

BuiltInFunctionEmulator::FunctionId BuiltInFunctionEmulator::addEmulatedFunctionWithDependency(
    FunctionId dependency,
    TOperator op,
    const TType *param1,
    const TType *param2,
    const char *emulatedFunctionDefinition)
{
    FunctionId id(op, param1, param2);
    mEmulatedFunctions[id]    = std::string(emulatedFunctionDefinition);
    mFunctionDependencies[id] = dependency;
    return id;
}

BuiltInFunctionEmulator::FunctionId BuiltInFunctionEmulator::addEmulatedFunction(
    TOperator op,
    const TType *param1,
    const TType *param2,
    const TType *param3,
    const char *emulatedFunctionDefinition)
{
    FunctionId id(op, param1, param2, param3);
    mEmulatedFunctions[id] = std::string(emulatedFunctionDefinition);
    return id;
}

BuiltInFunctionEmulator::FunctionId BuiltInFunctionEmulator::addEmulatedFunction(
    TOperator op,
    const TType *param1,
    const TType *param2,
    const TType *param3,
    const TType *param4,
    const char *emulatedFunctionDefinition)
{
    FunctionId id(op, param1, param2, param3, param4);
    mEmulatedFunctions[id] = std::string(emulatedFunctionDefinition);
    return id;
}

BuiltInFunctionEmulator::FunctionId BuiltInFunctionEmulator::addEmulatedFunctionWithDependency(
    FunctionId dependency,
    TOperator op,
    const TType *param1,
    const TType *param2,
    const TType *param3,
    const TType *param4,
    const char *emulatedFunctionDefinition)
{
    FunctionId id(op, param1, param2, param3, param4);
    mEmulatedFunctions[id]    = std::string(emulatedFunctionDefinition);
    mFunctionDependencies[id] = dependency;
    return id;
}

bool BuiltInFunctionEmulator::isOutputEmpty() const
{
    return (mFunctions.size() == 0);
}

void BuiltInFunctionEmulator::outputEmulatedFunctions(TInfoSinkBase &out) const
{
    for (size_t i = 0; i < mFunctions.size(); ++i)
    {
        out << mEmulatedFunctions.find(mFunctions[i])->second << "\n\n";
    }
}

bool BuiltInFunctionEmulator::setFunctionCalled(TOperator op, const TType &param)
{
    return setFunctionCalled(FunctionId(op, &param));
}

bool BuiltInFunctionEmulator::setFunctionCalled(TOperator op,
                                                const TType &param1,
                                                const TType &param2)
{
    return setFunctionCalled(FunctionId(op, &param1, &param2));
}

bool BuiltInFunctionEmulator::setFunctionCalled(TOperator op,
                                                const TType &param1,
                                                const TType &param2,
                                                const TType &param3)
{
    return setFunctionCalled(FunctionId(op, &param1, &param2, &param3));
}

bool BuiltInFunctionEmulator::setFunctionCalled(TOperator op,
                                                const TType &param1,
                                                const TType &param2,
                                                const TType &param3,
                                                const TType &param4)
{
    return setFunctionCalled(FunctionId(op, &param1, &param2, &param3, &param4));
}

bool BuiltInFunctionEmulator::setFunctionCalled(const FunctionId &functionId)
{
    if (mEmulatedFunctions.find(functionId) != mEmulatedFunctions.end())
    {
        for (size_t i = 0; i < mFunctions.size(); ++i)
        {
            if (mFunctions[i] == functionId)
                return true;
        }
        // If the function depends on another, mark the dependency as called.
        auto dependency = mFunctionDependencies.find(functionId);
        if (dependency != mFunctionDependencies.end())
        {
            setFunctionCalled((*dependency).second);
        }
        // Copy the functionId if it needs to be stored, to make sure that the TType pointers inside
        // remain valid and constant.
        mFunctions.push_back(functionId.getCopy());
        return true;
    }
    return false;
}

void BuiltInFunctionEmulator::markBuiltInFunctionsForEmulation(TIntermNode *root)
{
    ASSERT(root);

    if (mEmulatedFunctions.empty())
        return;

    BuiltInFunctionEmulationMarker marker(*this);
    root->traverse(&marker);
}

void BuiltInFunctionEmulator::cleanup()
{
    mFunctions.clear();
    mFunctionDependencies.clear();
}

// static
void BuiltInFunctionEmulator::WriteEmulatedFunctionName(TInfoSinkBase &out, const char *name)
{
    ASSERT(name[strlen(name) - 1] != '(');
    out << "webgl_" << name << "_emu";
}

BuiltInFunctionEmulator::FunctionId::FunctionId()
    : mOp(EOpNull),
      mParam1(TCache::getType(EbtVoid)),
      mParam2(TCache::getType(EbtVoid)),
      mParam3(TCache::getType(EbtVoid)),
      mParam4(TCache::getType(EbtVoid))
{
}

BuiltInFunctionEmulator::FunctionId::FunctionId(TOperator op, const TType *param)
    : mOp(op),
      mParam1(param),
      mParam2(TCache::getType(EbtVoid)),
      mParam3(TCache::getType(EbtVoid)),
      mParam4(TCache::getType(EbtVoid))
{
}

BuiltInFunctionEmulator::FunctionId::FunctionId(TOperator op,
                                                const TType *param1,
                                                const TType *param2)
    : mOp(op),
      mParam1(param1),
      mParam2(param2),
      mParam3(TCache::getType(EbtVoid)),
      mParam4(TCache::getType(EbtVoid))
{
}

BuiltInFunctionEmulator::FunctionId::FunctionId(TOperator op,
                                                const TType *param1,
                                                const TType *param2,
                                                const TType *param3)
    : mOp(op), mParam1(param1), mParam2(param2), mParam3(param3), mParam4(TCache::getType(EbtVoid))
{
}

BuiltInFunctionEmulator::FunctionId::FunctionId(TOperator op,
                                                const TType *param1,
                                                const TType *param2,
                                                const TType *param3,
                                                const TType *param4)
    : mOp(op), mParam1(param1), mParam2(param2), mParam3(param3), mParam4(param4)
{
}

bool BuiltInFunctionEmulator::FunctionId::operator==(
    const BuiltInFunctionEmulator::FunctionId &other) const
{
    return (mOp == other.mOp && *mParam1 == *other.mParam1 && *mParam2 == *other.mParam2 &&
            *mParam3 == *other.mParam3 && *mParam4 == *other.mParam4);
}

bool BuiltInFunctionEmulator::FunctionId::operator<(
    const BuiltInFunctionEmulator::FunctionId &other) const
{
    if (mOp != other.mOp)
        return mOp < other.mOp;
    if (*mParam1 != *other.mParam1)
        return *mParam1 < *other.mParam1;
    if (*mParam2 != *other.mParam2)
        return *mParam2 < *other.mParam2;
    if (*mParam3 != *other.mParam3)
        return *mParam3 < *other.mParam3;
    if (*mParam4 != *other.mParam4)
        return *mParam4 < *other.mParam4;
    return false;  // all fields are equal
}

BuiltInFunctionEmulator::FunctionId BuiltInFunctionEmulator::FunctionId::getCopy() const
{
    return FunctionId(mOp, new TType(*mParam1), new TType(*mParam2), new TType(*mParam3),
                      new TType(*mParam4));
}

}  // namespace sh
