// Copyright 2021 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef SRC_TINT_LANG_CORE_INTRINSIC_TABLE_H_
#define SRC_TINT_LANG_CORE_INTRINSIC_TABLE_H_

#include <memory>
#include <string>
#include <utility>

#include "src/tint/lang/core/binary_op.h"
#include "src/tint/lang/core/builtin_fn.h"
#include "src/tint/lang/core/intrinsic/ctor_conv.h"
#include "src/tint/lang/core/intrinsic/table_data.h"
#include "src/tint/lang/core/parameter_usage.h"
#include "src/tint/lang/core/unary_op.h"
#include "src/tint/utils/containers/vector.h"
#include "src/tint/utils/text/string.h"
#include "src/tint/utils/text/string_stream.h"
#include "src/tint/utils/text/styled_text.h"

// Forward declarations
namespace tint::diag {
class List;
}  // namespace tint::diag

namespace tint::core::intrinsic {

/// Overload describes a fully matched builtin function overload
struct Overload {
    static constexpr size_t kNumFixedParameters = 8;

    /// Parameter describes a single parameter
    struct Parameter {
        /// Parameter type
        const core::type::Type* const type;
        /// Parameter usage
        core::ParameterUsage const usage = core::ParameterUsage::kNone;

        /// Equality operator
        /// @param other the parameter to compare against
        /// @returns true if this parameter and @p other are the same
        bool operator==(const Parameter& other) const {
            return type == other.type && usage == other.usage;
        }

        /// Inequality operator
        /// @param other the parameter to compare against
        /// @returns false if this parameter and @p other are the same
        bool operator!=(const Parameter& other) const { return !(*this == other); }
    };

    /// The overload information
    const OverloadInfo* info = nullptr;

    /// The resolved overload return type
    core::type::Type const* return_type = nullptr;

    /// The resolved overload parameters
    Vector<Parameter, kNumFixedParameters> parameters;

    /// The constant evaluation function
    constant::Eval::Function const_eval_fn = nullptr;

    /// Equality operator
    /// @param other the overload to compare against
    /// @returns true if this overload and @p other are the same
    bool operator==(const Overload& other) const {
        return info == other.info && return_type == other.return_type &&
               parameters == other.parameters;
    }

    /// Inequality operator
    /// @param other the overload to compare against
    /// @returns false if this overload and @p other are the same
    bool operator!=(const Overload& other) const { return !(*this == other); }
};

/// The context data used to lookup intrinsic information
struct Context {
    /// The table table
    const TableData& data;
    /// The type manager
    core::type::Manager& types;
    /// The symbol table
    SymbolTable& symbols;
};

/// Candidate holds information about an overload evaluated for resolution.
struct Candidate {
    /// The match-score of the candidate overload.
    /// A score of zero indicates an exact match.
    /// Non-zero scores are used for diagnostics when no overload matches.
    /// Lower scores are displayed first (top-most).
    size_t score = 0;
    /// The candidate overload
    const OverloadInfo* overload = nullptr;
    /// The template types and numbers
    TemplateState templates{};
    /// The parameter types for the candidate overload
    Vector<Overload::Parameter, Overload::kNumFixedParameters> parameters{};
};

// Prints the candidate overload for emitting diagnostics
void PrintCandidate(StyledText& ss,
                    Context& context,
                    const Candidate& candidate,
                    std::string_view intrinsic_name,
                    VectorRef<const core::type::Type*> template_args,
                    VectorRef<const core::type::Type*> args);

/// Lookup looks for the builtin overload with the given signature, raising an error diagnostic
/// if the builtin was not found.
/// @param context the intrinsic context
/// @param function_name the name of the function
/// @param function_id the function identifier
/// @param template_args the optional template arguments
/// @param args the argument types passed to the builtin function
/// @param earliest_eval_stage the the earliest evaluation stage that a call to
///        the builtin can be made. This can alter the overloads considered.
///        For example, if the earliest evaluation stage is `EvaluationStage::kRuntime`, then
///        only overloads with concrete argument types will be considered, as all
///        abstract-numerics will have been materialized after shader creation time
///        (EvaluationStage::kConstant).
/// @return the resolved builtin function overload
Result<Overload, StyledText> LookupFn(Context& context,
                                      std::string_view function_name,
                                      size_t function_id,
                                      VectorRef<const core::type::Type*> template_args,
                                      VectorRef<const core::type::Type*> args,
                                      EvaluationStage earliest_eval_stage);

/// Lookup looks for the unary op overload with the given signature, raising an error
/// diagnostic if the operator was not found.
/// @param context the intrinsic context
/// @param op the unary operator
/// @param arg the type of the expression passed to the operator
/// @param earliest_eval_stage the the earliest evaluation stage that a call to
///        the unary operator can be made. This can alter the overloads considered.
///        For example, if the earliest evaluation stage is
///        `EvaluationStage::kRuntime`, then only overloads with concrete argument types
///        will be considered, as all abstract-numerics will have been materialized
///        after shader creation time (EvaluationStage::kConstant).
/// @return the resolved unary operator overload
Result<Overload, StyledText> LookupUnary(Context& context,
                                         core::UnaryOp op,
                                         const core::type::Type* arg,
                                         EvaluationStage earliest_eval_stage);

/// Lookup looks for the binary op overload with the given signature, raising an error
/// diagnostic if the operator was not found.
/// @param context the intrinsic context
/// @param op the binary operator
/// @param lhs the LHS value type passed to the operator
/// @param rhs the RHS value type passed to the operator
/// @param earliest_eval_stage the the earliest evaluation stage that a call to
///        the binary operator can be made. This can alter the overloads considered.
///        For example, if the earliest evaluation stage is
///        `EvaluationStage::kRuntime`, then only overloads with concrete argument types
///        will be considered, as all abstract-numerics will have been materialized
///        after shader creation time (EvaluationStage::kConstant).
/// @param is_compound true if the binary operator is being used as a compound assignment
/// @return the resolved binary operator overload
Result<Overload, StyledText> LookupBinary(Context& context,
                                          core::BinaryOp op,
                                          const core::type::Type* lhs,
                                          const core::type::Type* rhs,
                                          EvaluationStage earliest_eval_stage,
                                          bool is_compound);

/// Lookup looks for the value constructor or conversion overload for the given CtorConv.
/// @param context the intrinsic context
/// @param type_name the name of the type being constructed or converted
/// @param type_id the type identifier
/// @param template_args the optional template arguments
/// @param args the argument types passed to the constructor / conversion call
/// @param earliest_eval_stage the the earliest evaluation stage that a call to
///        the constructor or conversion can be made. This can alter the overloads considered.
///        For example, if the earliest evaluation stage is
///        `EvaluationStage::kRuntime`, then only overloads with concrete argument types
///        will be considered, as all abstract-numerics will have been materialized
///        after shader creation time (EvaluationStage::kConstant).
/// @return the resolved type constructor or conversion function overload
Result<Overload, StyledText> LookupCtorConv(Context& context,
                                            std::string_view type_name,
                                            size_t type_id,
                                            VectorRef<const core::type::Type*> template_args,
                                            VectorRef<const core::type::Type*> args,
                                            EvaluationStage earliest_eval_stage);

/// Table is a wrapper around a dialect to provide type-safe interface to the intrinsic table.
template <typename DIALECT>
struct Table {
    /// Alias to DIALECT::BuiltinFn
    using BuiltinFn = typename DIALECT::BuiltinFn;

    /// Alias to DIALECT::CtorConv
    using CtorConv = typename DIALECT::CtorConv;

    static_assert(std::is_enum_v<BuiltinFn>);
    static_assert(std::is_enum_v<CtorConv>);

    /// @param types The type manager
    /// @param symbols The symbol table
    Table(core::type::Manager& types, SymbolTable& symbols)
        : context{DIALECT::kData, types, symbols} {}

    /// Lookup looks for the builtin overload with the given signature, raising an error diagnostic
    /// if the builtin was not found.
    /// @param builtin_fn the builtin function
    /// @param template_args the optional template arguments
    /// @param args the argument types passed to the builtin function
    /// @param earliest_eval_stage the the earliest evaluation stage that a call to
    ///        the builtin can be made. This can alter the overloads considered.
    ///        For example, if the earliest evaluation stage is `EvaluationStage::kRuntime`, then
    ///        only overloads with concrete argument types will be considered, as all
    ///        abstract-numerics will have been materialized after shader creation time
    ///        (EvaluationStage::kConstant).
    /// @return the resolved builtin function overload
    Result<Overload, StyledText> Lookup(BuiltinFn builtin_fn,
                                        VectorRef<const core::type::Type*> template_args,
                                        VectorRef<const core::type::Type*> args,
                                        EvaluationStage earliest_eval_stage) {
        std::string_view name = DIALECT::ToString(builtin_fn);
        size_t id = static_cast<size_t>(builtin_fn);
        return LookupFn(context, name, id, std::move(template_args), std::move(args),
                        earliest_eval_stage);
    }

    /// Lookup looks for the unary op overload with the given signature, raising an error
    /// diagnostic if the operator was not found.
    /// @param op the unary operator
    /// @param arg the type of the expression passed to the operator
    /// @param earliest_eval_stage the the earliest evaluation stage that a call to
    ///        the unary operator can be made. This can alter the overloads considered.
    ///        For example, if the earliest evaluation stage is
    ///        `EvaluationStage::kRuntime`, then only overloads with concrete argument types
    ///        will be considered, as all abstract-numerics will have been materialized
    ///        after shader creation time (EvaluationStage::kConstant).

    /// @return the resolved unary operator overload
    Result<Overload, StyledText> Lookup(core::UnaryOp op,
                                        const core::type::Type* arg,
                                        EvaluationStage earliest_eval_stage) {
        return LookupUnary(context, op, arg, earliest_eval_stage);
    }

    /// Lookup looks for the binary op overload with the given signature, raising an error
    /// diagnostic if the operator was not found.
    /// @param op the binary operator
    /// @param lhs the LHS value type passed to the operator
    /// @param rhs the RHS value type passed to the operator
    /// @param earliest_eval_stage the the earliest evaluation stage that a call to
    ///        the binary operator can be made. This can alter the overloads considered.
    ///        For example, if the earliest evaluation stage is
    ///        `EvaluationStage::kRuntime`, then only overloads with concrete argument types
    ///        will be considered, as all abstract-numerics will have been materialized
    ///        after shader creation time (EvaluationStage::kConstant).

    /// @param is_compound true if the binary operator is being used as a compound assignment
    /// @return the resolved binary operator overload
    Result<Overload, StyledText> Lookup(core::BinaryOp op,
                                        const core::type::Type* lhs,
                                        const core::type::Type* rhs,
                                        EvaluationStage earliest_eval_stage,
                                        bool is_compound) {
        return LookupBinary(context, op, lhs, rhs, earliest_eval_stage, is_compound);
    }

    /// Lookup looks for the value constructor or conversion overload for the given CtorConv.
    /// @param type the type being constructed or converted
    /// @param template_args the optional template arguments
    /// @param args the argument types passed to the constructor / conversion call
    /// @param earliest_eval_stage the the earliest evaluation stage that a call to
    ///        the constructor or conversion can be made. This can alter the overloads considered.
    ///        For example, if the earliest evaluation stage is
    ///        `EvaluationStage::kRuntime`, then only overloads with concrete argument types
    ///        will be considered, as all abstract-numerics will have been materialized
    ///        after shader creation time (EvaluationStage::kConstant).
    /// @return the resolved type constructor or conversion function overload
    Result<Overload, StyledText> Lookup(CtorConv type,
                                        VectorRef<const core::type::Type*> template_args,
                                        VectorRef<const core::type::Type*> args,
                                        EvaluationStage earliest_eval_stage) {
        std::string_view name = DIALECT::ToString(type);
        size_t id = static_cast<size_t>(type);
        return LookupCtorConv(context, name, id, std::move(template_args), std::move(args),
                              earliest_eval_stage);
    }

    /// The intrinsic context
    Context context;
};

}  // namespace tint::core::intrinsic

namespace tint {

/// Hasher specialization for core::intrinsic::Overload
template <>
struct Hasher<core::intrinsic::Overload> {
    /// @param i the core::intrinsic::Overload to create a hash for
    /// @return the hash value
    inline HashCode operator()(const core::intrinsic::Overload& i) const {
        HashCode hash = Hash(i.parameters.Length());
        for (auto& p : i.parameters) {
            hash = HashCombine(hash, p.type, p.usage);
        }
        return Hash(hash, i.info, i.return_type);
    }
};

}  // namespace tint

#endif  // SRC_TINT_LANG_CORE_INTRINSIC_TABLE_H_
