// Copyright 2021 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_LANG_WGSL_AST_TRANSFORM_HELPER_TEST_H_
#define SRC_TINT_LANG_WGSL_AST_TRANSFORM_HELPER_TEST_H_

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

#include "gtest/gtest.h"
#include "src/tint/lang/wgsl/ast/transform/manager.h"
#include "src/tint/lang/wgsl/ast/transform/transform.h"
#include "src/tint/lang/wgsl/reader/reader.h"
#include "src/tint/lang/wgsl/writer/writer.h"

namespace tint::ast::transform {

/// @param program the program to get an output WGSL string from
/// @returns the output program as a WGSL string, or an error string if the
/// program is not valid.
inline std::string str(const Program& program) {
    if (!program.IsValid()) {
        return program.Diagnostics().str();
    }

    wgsl::writer::Options options;
    auto result = wgsl::writer::Generate(&program, options);
    if (!result) {
        return "WGSL writer failed:\n" + result.Failure();
    }

    auto res = result->wgsl;
    if (res.empty()) {
        return res;
    }
    // The WGSL sometimes has two trailing newlines. Strip them
    while (res.back() == '\n') {
        res.pop_back();
    }
    if (res.empty()) {
        return res;
    }
    return "\n" + res + "\n";
}

/// Helper class for testing transforms
template <typename BASE>
class TransformTestBase : public BASE {
  public:
    /// Transforms and returns the WGSL source `in`, transformed using
    /// `transform`.
    /// @param transform the transform to apply
    /// @param in the input WGSL source
    /// @param data the optional DataMap to pass to Transform::Run()
    /// @return the transformed output
    Output Run(std::string in,
               std::unique_ptr<transform::Transform> transform,
               const DataMap& data = {}) {
        std::vector<std::unique_ptr<transform::Transform>> transforms;
        transforms.emplace_back(std::move(transform));
        return Run(std::move(in), std::move(transforms), data);
    }

    /// Transforms and returns the WGSL source `in`, transformed using
    /// a transform of type `TRANSFORM`.
    /// @param in the input WGSL source
    /// @param data the optional DataMap to pass to Transform::Run()
    /// @return the transformed output
    template <typename... TRANSFORMS>
    Output Run(std::string in, const DataMap& data = {}) {
        auto file = std::make_unique<Source::File>("test", in);
        auto program = wgsl::reader::Parse(file.get());

        // Keep this pointer alive after Transform() returns
        files_.emplace_back(std::move(file));

        return Run<TRANSFORMS...>(std::move(program), data);
    }

    /// Transforms and returns program `program`, transformed using a transform of
    /// type `TRANSFORM`.
    /// @param program the input Program
    /// @param data the optional DataMap to pass to Transform::Run()
    /// @return the transformed output
    template <typename... TRANSFORMS>
    Output Run(Program&& program, const DataMap& data = {}) {
        if (!program.IsValid()) {
            return Output(std::move(program));
        }

        Manager manager;
        DataMap outputs;
        for (auto* transform_ptr : std::initializer_list<Transform*>{new TRANSFORMS()...}) {
            manager.append(std::unique_ptr<Transform>(transform_ptr));
        }
        auto result = manager.Run(&program, data, outputs);
        return {std::move(result), std::move(outputs)};
    }

    /// @param program the input program
    /// @param data the optional DataMap to pass to Transform::Run()
    /// @return true if the transform should be run for the given input.
    template <typename TRANSFORM>
    bool ShouldRun(Program&& program, const DataMap& data = {}) {
        if (!program.IsValid()) {
            ADD_FAILURE() << "ShouldRun() called with invalid program: "
                          << program.Diagnostics().str();
            return false;
        }

        const Transform& t = TRANSFORM();

        DataMap outputs;
        auto result = t.Apply(&program, data, outputs);
        if (!result) {
            return false;
        }
        if (!result->IsValid()) {
            ADD_FAILURE() << "Apply() called by ShouldRun() returned errors: "
                          << result->Diagnostics().str();
            return true;
        }
        return result.has_value();
    }

    /// @param in the input WGSL source
    /// @param data the optional DataMap to pass to Transform::Run()
    /// @return true if the transform should be run for the given input.
    template <typename TRANSFORM>
    bool ShouldRun(std::string in, const DataMap& data = {}) {
        auto file = std::make_unique<Source::File>("test", in);
        auto program = wgsl::reader::Parse(file.get());
        return ShouldRun<TRANSFORM>(std::move(program), data);
    }

    /// @param output the output of the transform
    /// @returns the output program as a WGSL string, or an error string if the
    /// program is not valid.
    std::string str(const Output& output) { return transform::str(output.program); }

  private:
    std::vector<std::unique_ptr<Source::File>> files_;
};

using TransformTest = TransformTestBase<testing::Test>;

template <typename T>
using TransformTestWithParam = TransformTestBase<testing::TestWithParam<T>>;

}  // namespace tint::ast::transform

#endif  // SRC_TINT_LANG_WGSL_AST_TRANSFORM_HELPER_TEST_H_
