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

#include "src/sksl/ir/SkSLConstructorArray.h"

#include "include/core/SkTypes.h"
#include "include/private/SkSLString.h"
#include "include/sksl/SkSLErrorReporter.h"
#include "src/sksl/SkSLContext.h"
#include "src/sksl/SkSLProgramSettings.h"
#include "src/sksl/ir/SkSLConstructorArrayCast.h"
#include "src/sksl/ir/SkSLType.h"

#include <algorithm>
#include <string>

namespace SkSL {

std::unique_ptr<Expression> ConstructorArray::Convert(const Context& context,
                                                      Position pos,
                                                      const Type& type,
                                                      ExpressionArray args) {
    SkASSERTF(type.isArray() && type.columns() > 0, "%s", type.description().c_str());

    // ES2 doesn't support first-class array types.
    if (context.fConfig->strictES2Mode()) {
        context.fErrors->error(pos, "construction of array type '" + type.displayName() +
                "' is not supported");
        return nullptr;
    }

    // If there is a single argument containing an array of matching size and the types are
    // coercible, this is actually a cast. i.e., `half[10](myFloat10Array)`. This isn't a GLSL
    // feature, but the Pipeline stage code generator needs this functionality so that code which
    // was originally compiled with "allow narrowing conversions" enabled can be later recompiled
    // without narrowing conversions (we patch over these conversions with an explicit cast).
    if (args.size() == 1) {
        const Expression& expr = *args.front();
        const Type& exprType = expr.type();

        if (exprType.isArray() && exprType.canCoerceTo(type, /*allowNarrowing=*/true)) {
            return ConstructorArrayCast::Make(context, pos, type, std::move(args.front()));
        }
    }

    // Check that the number of constructor arguments matches the array size.
    if (type.columns() != args.count()) {
        context.fErrors->error(pos, String::printf("invalid arguments to '%s' constructor "
                "(expected %d elements, but found %d)", type.displayName().c_str(), type.columns(),
                args.count()));
        return nullptr;
    }

    // Convert each constructor argument to the array's component type.
    const Type& baseType = type.componentType();
    for (std::unique_ptr<Expression>& argument : args) {
        argument = baseType.coerceExpression(std::move(argument), context);
        if (!argument) {
            return nullptr;
        }
    }

    return ConstructorArray::Make(context, pos, type, std::move(args));
}

std::unique_ptr<Expression> ConstructorArray::Make(const Context& context,
                                                   Position pos,
                                                   const Type& type,
                                                   ExpressionArray args) {
    SkASSERT(!context.fConfig->strictES2Mode());
    SkASSERT(type.isAllowedInES2(context));
    SkASSERT(type.columns() == args.count());
    SkASSERT(std::all_of(args.begin(), args.end(), [&](const std::unique_ptr<Expression>& arg) {
        return type.componentType().matches(arg->type());
    }));

    return std::make_unique<ConstructorArray>(pos, type, std::move(args));
}

}  // namespace SkSL
