// Copyright 2022 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef SRC_TINT_IR_TEST_HELPER_H_
#define SRC_TINT_IR_TEST_HELPER_H_

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

#include "gtest/gtest.h"
#include "src/tint/ir/builder_impl.h"
#include "src/tint/ir/disassembler.h"
#include "src/tint/number.h"
#include "src/tint/program_builder.h"

namespace tint::ir {

/// Helper class for testing
template <typename BASE>
class TestHelperBase : public BASE, public ProgramBuilder {
  public:
    TestHelperBase() = default;

    ~TestHelperBase() override = default;

    /// Builds and returns a BuilderImpl from the program.
    /// @note The builder is only created once. Multiple calls to Build() will
    /// return the same builder without rebuilding.
    /// @return the builder
    BuilderImpl& CreateBuilder() {
        if (gen_) {
            return *gen_;
        }
        diag::Formatter formatter;

        program_ = std::make_unique<Program>(std::move(*this));
        [&]() { ASSERT_TRUE(program_->IsValid()) << formatter.format(program_->Diagnostics()); }();
        gen_ = std::make_unique<BuilderImpl>(program_.get());
        return *gen_;
    }

    /// Injects a flow block into the builder
    /// @returns the injected block
    ir::Block* InjectFlowBlock() {
        auto* block = gen_->builder.CreateBlock();
        gen_->current_flow_block = block;
        return block;
    }

    /// Creates a BuilderImpl without an originating program. This is used for testing the
    /// expressions which don't require the full builder implementation. The current flow block
    /// is initialized with an empty block.
    /// @returns the BuilderImpl for testing.
    BuilderImpl& CreateEmptyBuilder() {
        program_ = std::make_unique<Program>();
        gen_ = std::make_unique<BuilderImpl>(program_.get());
        gen_->current_flow_block = gen_->builder.CreateBlock();
        return *gen_;
    }

    /// Build the module, cleaning up the program before returning.
    /// @returns the generated module
    utils::Result<Module> Build() {
        auto& b = CreateBuilder();
        auto m = b.Build();

        // Store the error away in case we need it
        error_ = b.error();

        // Explicitly remove program to guard against pointers back to ast. Note, this does mean the
        // BuilderImpl is pointing to an invalid program. We keep the BuilderImpl around because we
        // need to be able to map from ast pointers to flow nodes in tests.
        program_ = nullptr;
        return m;
    }

    /// @param node the ast node to lookup
    /// @returns the IR flow node for the given ast node.
    const ir::FlowNode* FlowNodeForAstNode(const ast::Node* node) const {
        return gen_->FlowNodeForAstNode(node);
    }

    /// @param mod the module
    /// @returns the disassembly string of the module
    std::string Disassemble(Module& mod) const {
        Disassembler d(mod);
        return d.Disassemble();
    }

    /// @returns the error generated during build, if any
    std::string Error() const { return error_; }

  private:
    std::unique_ptr<BuilderImpl> gen_;

    /// The program built with a call to Build()
    std::unique_ptr<Program> program_;

    /// Error generated when calling `Build`
    std::string error_;
};
using TestHelper = TestHelperBase<testing::Test>;

template <typename T>
using TestParamHelper = TestHelperBase<testing::TestWithParam<T>>;

}  // namespace tint::ir

#endif  // SRC_TINT_IR_TEST_HELPER_H_
