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

#include "include/core/SkTypes.h"
#include "include/private/SkSLProgramElement.h"
#include "include/private/SkTHash.h"
#include "src/sksl/SkSLBuiltinMap.h"
#include "src/sksl/SkSLContext.h"
#include "src/sksl/SkSLIntrinsicList.h"
#include "src/sksl/SkSLProgramSettings.h"
#include "src/sksl/analysis/SkSLProgramUsage.h"
#include "src/sksl/ir/SkSLFunctionDeclaration.h"
#include "src/sksl/ir/SkSLFunctionDefinition.h"
#include "src/sksl/ir/SkSLProgram.h"
#include "src/sksl/transform/SkSLTransform.h"

#include <algorithm>
#include <cstddef>
#include <memory>
#include <string>
#include <string_view>
#include <vector>

namespace SkSL {

void Transform::FindAndDeclareBuiltinFunctions(Program& program) {
    ProgramUsage* usage = program.fUsage.get();
    Context& context = *program.fContext;

    std::vector<const FunctionDefinition*> addedBuiltins;
    for (;;) {
        // Find all the built-ins referenced by the program but not yet included in the code.
        size_t numBuiltinsAtStart = addedBuiltins.size();
        for (const auto& [fn, count] : usage->fCallCounts) {
            if (!fn->isBuiltin() || count == 0) {
                // Not a built-in; skip it.
                continue;
            }
            if (fn->intrinsicKind() == k_dFdy_IntrinsicKind) {
                // Programs that invoke the `dFdy` intrinsic will need the RTFlip input.
                program.fInputs.fUseFlipRTUniform = !context.fConfig->fSettings.fForceNoRTFlip;
            }
            if (const ProgramElement* elem = context.fBuiltins->find(fn->description())) {
                // Make sure we only add a built-in function once. We rarely add more than a handful
                // of builtin functions, so linear search here is good enough.
                const FunctionDefinition* builtinDef = &elem->as<FunctionDefinition>();
                if (std::find(addedBuiltins.begin(), addedBuiltins.end(), builtinDef) ==
                    addedBuiltins.end()) {
                    addedBuiltins.push_back(builtinDef);
                }
            }
        }

        if (addedBuiltins.size() == numBuiltinsAtStart) {
            // If we didn't reference any more built-in functions than before, we're done.
            break;
        }

        // Sort the referenced builtin functions into a consistent order; otherwise our output will
        // become non-deterministic. The exact order isn't particularly important; we sort backwards
        // because we add elements to the shared-elements in reverse order at the end.
        std::sort(addedBuiltins.begin() + numBuiltinsAtStart,
                  addedBuiltins.end(),
                  [](const FunctionDefinition* aDefinition, const FunctionDefinition* bDefinition) {
                      const FunctionDeclaration& a = aDefinition->declaration();
                      const FunctionDeclaration& b = bDefinition->declaration();
                      if (a.name() != b.name()) {
                          return a.name() > b.name();
                      }
                      return a.description() > b.description();
                  });

        // Update the ProgramUsage to track all these newly discovered functions.
        int usageCallCounts = usage->fCallCounts.count();

        for (size_t index = numBuiltinsAtStart; index < addedBuiltins.size(); ++index) {
            usage->add(*addedBuiltins[index]);
        }

        if (usage->fCallCounts.count() == usageCallCounts) {
            // If we aren't making any more unique function calls than before, we're done.
            break;
        }
    }

    // Insert the new functions into the program's shared elements, right at the front.
    // They are added in reverse so that the deepest dependencies are added to the top.
    program.fSharedElements.insert(program.fSharedElements.begin(),
                                   addedBuiltins.rbegin(), addedBuiltins.rend());
}

}  // namespace SkSL
