// 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 <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_;
    }

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

  private:
    std::unique_ptr<BuilderImpl> gen_;
};
using TestHelper = TestHelperBase<testing::Test>;

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

}  // namespace tint::ir

#endif  // SRC_TINT_IR_TEST_HELPER_H_
