// Copyright 2023 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_IR_CLONE_CONTEXT_H_
#define SRC_TINT_LANG_CORE_IR_CLONE_CONTEXT_H_

#include "src/tint/utils/containers/hashmap.h"
#include "src/tint/utils/containers/transform.h"
#include "src/tint/utils/traits/traits.h"

namespace tint::core::ir {
class Block;
class Instruction;
class Module;
class Value;
}  // namespace tint::core::ir

namespace tint::core::ir {

/// Constant in the IR.
class CloneContext {
  public:
    /// @param module the IR module
    explicit CloneContext(Module& module);

    /// The IR module
    Module& ir;

    /// Performs a clone of @p what.
    /// @param what the item to clone
    /// @return the cloned item
    template <typename T>
    T* Clone(T* what) {
        if (auto replacement = replacements_.Get(what)) {
            return (*replacement)->template As<T>();
        }
        T* result = what->Clone(*this);
        Replace(what, result);
        return result;
    }

    /// Performs a clone of all the elements in @p what.
    /// @param what the elements to clone
    /// @return the cloned elements
    template <size_t N, typename T>
    Vector<T*, N> Clone(Slice<T* const> what) {
        return Transform<N>(what, [&](T* const p) { return Clone(p); });
    }

    /// Performs a clone of all the elements in @p what.
    /// @param what the elements to clone
    /// @return the cloned elements
    template <size_t N, typename T>
    Vector<T*, N> Clone(Slice<T*> what) {
        return Transform<N>(what, [&](T* p) { return Clone(p); });
    }

    /// Performs a clone of all the elements in @p what.
    /// @param what the elements to clone
    /// @return the cloned elements
    template <size_t N, typename T>
    Vector<T*, N> Clone(Vector<T*, N> what) {
        return Transform(what, [&](T* p) { return Clone(p); });
    }

    /// Obtains the (potentially) remapped pointer to @p what
    /// @param what the item
    /// @return the cloned item for @p what, or the original pointer if @p what has not been cloned.
    template <typename T>
    T* Remap(T* what) {
        if (auto replacement = replacements_.Get(what)) {
            return (*replacement)->template As<T>();
        }
        return what;
    }

    /// Obtains the (potentially) remapped pointer of all the elements in @p what.
    /// @param what the item
    /// @return the remapped elements
    template <size_t N, typename T>
    Vector<T*, N> Remap(Slice<T* const> what) {
        return Transform<N>(what, [&](T* const p) { return Remap(p); });
    }

    /// Obtains the (potentially) remapped pointer of all the elements in @p what.
    /// @param what the item
    /// @return the remapped elements
    template <size_t N, typename T>
    Vector<T*, N> Remap(Slice<T*> what) {
        return Transform<N>(what, [&](T* p) { return Remap(p); });
    }

    /// Obtains the (potentially) remapped pointer of all the elements in @p what.
    /// @param what the item
    /// @return the remapped elements
    template <size_t N, typename T>
    Vector<T*, N> Remap(Vector<T*, N> what) {
        return Transform(what, [&](T* p) { return Remap(p); });
    }

    /// Registers the replacement of `what` with `with`
    /// @param what the value or instruction to replace
    /// @param with a pointer to a replacement value or instruction
    template <typename WHAT, typename WITH>
    void Replace(WHAT* what, WITH* with) {
        static_assert(traits::IsTypeOrDerived<WHAT, ir::Instruction> ||
                      traits::IsTypeOrDerived<WHAT, ir::Value>);
        static_assert(traits::IsTypeOrDerived<WITH, WHAT>);
        TINT_ASSERT(with);
        replacements_.Add(what, with);
    }

  private:
    Hashmap<CastableBase*, CastableBase*, 8> replacements_;
};

}  // namespace tint::core::ir

#endif  // SRC_TINT_LANG_CORE_IR_CLONE_CONTEXT_H_
