// Copyright 2022 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_WGSL_AST_TRANSFORM_BUILTIN_POLYFILL_H_
#define SRC_TINT_LANG_WGSL_AST_TRANSFORM_BUILTIN_POLYFILL_H_

#include "src/tint/lang/wgsl/ast/transform/transform.h"
#include "src/tint/utils/reflection/reflection.h"

namespace tint::ast::transform {

/// Implements builtins for backends that do not have a native implementation.
class BuiltinPolyfill final : public Castable<BuiltinPolyfill, Transform> {
  public:
    /// Constructor
    BuiltinPolyfill();
    /// Destructor
    ~BuiltinPolyfill() override;

    /// Enumerator of polyfill levels
    enum class Level {
        /// No polyfill needed, supported by the backend.
        kNone,
        /// Clamp the parameters to the inner implementation.
        kClampParameters,
        /// Range check the input.
        kRangeCheck,
        /// Polyfill the entire function
        kFull,
    };

    /// Specifies the builtins that should be polyfilled by the transform.
    struct Builtins {
        /// What level should `acosh` be polyfilled?
        Level acosh = Level::kNone;
        /// Should `asinh` be polyfilled?
        bool asinh = false;
        /// What level should `atanh` be polyfilled?
        Level atanh = Level::kNone;
        /// Should storage textures of format 'bgra8unorm' be replaced with 'rgba8unorm'?
        bool bgra8unorm = false;
        /// Should the RHS of `<<` and `>>` be wrapped in a modulo bit-width of LHS?
        bool bitshift_modulo = false;
        /// Should `clamp()` be polyfilled for integer values (scalar or vector)?
        bool clamp_int = false;
        /// Should `countLeadingZeros()` be polyfilled?
        bool count_leading_zeros = false;
        /// Should `countTrailingZeros()` be polyfilled?
        bool count_trailing_zeros = false;
        /// Should converting f32 to i32 or u32 be polyfilled?
        bool conv_f32_to_iu32 = false;
        /// What level should `extractBits()` be polyfilled?
        Level extract_bits = Level::kNone;
        /// Should `firstLeadingBit()` be polyfilled?
        bool first_leading_bit = false;
        /// Should `firstTrailingBit()` be polyfilled?
        bool first_trailing_bit = false;
        /// Should `fwidthFine()` be polyfilled?
        bool fwidth_fine = false;
        /// Should `insertBits()` be polyfilled?
        Level insert_bits = Level::kNone;
        /// Should integer scalar / vector divides and modulos be polyfilled to avoid DBZ and
        /// integer overflows?
        bool int_div_mod = false;
        /// Should float modulos be polyfilled to emit a precise modulo operation as per the spec?
        bool precise_float_mod = false;
        /// Should `reflect()` be polyfilled for vec2<f32>?
        bool reflect_vec2_f32 = false;
        /// Should `saturate()` be polyfilled?
        bool saturate = false;
        /// Should `sign()` be polyfilled for integer types?
        bool sign_int = false;
        /// Should `textureSampleBaseClampToEdge()` be polyfilled for texture_2d<f32> textures?
        bool texture_sample_base_clamp_to_edge_2d_f32 = false;
        /// Should the vector form of `quantizeToF16()` be polyfilled with a scalar implementation?
        /// See crbug.com/tint/1741
        bool quantize_to_vec_f16 = false;
        /// Should `workgroupUniformLoad()` be polyfilled?
        bool workgroup_uniform_load = false;
        /// Should `dot4I8Packed()` and `dot4U8Packed()` be polyfilled?
        bool dot_4x8_packed = false;
        /// Should `pack4xI8()`, `pack4xU8()`, `pack4xI8Clamp()`, `unpack4xI8()` and `unpack4xU8()`
        /// be polyfilled?
        bool pack_unpack_4x8 = false;
        /// Should `pack4xU8Clamp()` be polyfilled?
        /// TODO(tint:1497): remove the option once the bug in DXC is fixed.
        bool pack_4xu8_clamp = false;

        /// Reflection for this struct
        TINT_REFLECT(Builtins,
                     acosh,
                     asinh,
                     atanh,
                     bgra8unorm,
                     bitshift_modulo,
                     clamp_int,
                     count_leading_zeros,
                     count_trailing_zeros,
                     conv_f32_to_iu32,
                     extract_bits,
                     first_leading_bit,
                     first_trailing_bit,
                     fwidth_fine,
                     insert_bits,
                     int_div_mod,
                     precise_float_mod,
                     reflect_vec2_f32,
                     saturate,
                     sign_int,
                     texture_sample_base_clamp_to_edge_2d_f32,
                     quantize_to_vec_f16,
                     workgroup_uniform_load,
                     dot_4x8_packed,
                     pack_unpack_4x8,
                     pack_4xu8_clamp);
    };

    /// Config is consumed by the BuiltinPolyfill transform.
    /// Config specifies the builtins that should be polyfilled.
    struct Config final : public Castable<Config, Data> {
        /// Constructor
        Config();

        /// Constructor
        /// @param b the list of builtins to polyfill
        explicit Config(const Builtins& b);

        /// Copy constructor
        Config(const Config&);

        /// Destructor
        ~Config() override;

        /// The builtins to polyfill
        Builtins builtins;

        /// Reflection for this struct
        TINT_REFLECT(Config, builtins);
    };

    /// @copydoc Transform::Apply
    ApplyResult Apply(const Program& program,
                      const DataMap& inputs,
                      DataMap& outputs) const override;

  private:
    struct State;
};

}  // namespace tint::ast::transform

namespace tint {

/// Level reflection information
TINT_REFLECT_ENUM_RANGE(ast::transform::BuiltinPolyfill::Level, kNone, kFull);

}  // namespace tint

#endif  // SRC_TINT_LANG_WGSL_AST_TRANSFORM_BUILTIN_POLYFILL_H_
