// 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_TRANSFORM_TEST_HELPER_H_
#define SRC_TRANSFORM_TEST_HELPER_H_

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

#include "gtest/gtest.h"
#include "src/program.h"
#include "src/program_builder.h"
#include "src/reader/wgsl/parser.h"
#include "src/transform/manager.h"
#include "src/type_determiner.h"
#include "src/writer/wgsl/generator.h"

namespace tint {
namespace transform {

/// Helper class for testing transforms
class TransformTest : public testing::Test {
 public:
  /// Transforms and returns the WGSL source `in`, transformed using
  /// `transforms`.
  /// @param in the input WGSL source
  /// @param transforms the list of transforms to apply
  /// @return the transformed WGSL output
  std::string Transform(
      std::string in,
      std::vector<std::unique_ptr<transform::Transform>> transforms) {
    Source::File file("test", in);
    reader::wgsl::Parser parser(&file);
    if (!parser.Parse()) {
      return "WGSL reader failed:\n" + parser.error();
    }

    diag::Formatter::Style style;
    style.print_newline_at_end = false;

    auto program = parser.program();
    if (!program.IsValid()) {
      return diag::Formatter(style).format(program.Diagnostics());
    }

    {
      Manager manager;
      for (auto& transform : transforms) {
        manager.append(std::move(transform));
      }
      auto result = manager.Run(&program);

      if (result.diagnostics.contains_errors()) {
        return "manager().Run() errored:\n" +
               diag::Formatter(style).format(result.diagnostics);
      }
      program = std::move(result.program);
    }

    writer::wgsl::Generator generator(&program);
    if (!generator.Generate()) {
      return "WGSL writer failed:\n" + generator.error();
    }

    auto res = generator.result();
    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";
  }

  /// Transforms and returns the WGSL source `in`, transformed using
  /// `transform`.
  /// @param transform the transform to apply
  /// @param in the input WGSL source
  /// @return the transformed WGSL output
  std::string Transform(std::string in,
                        std::unique_ptr<transform::Transform> transform) {
    std::vector<std::unique_ptr<transform::Transform>> transforms;
    transforms.emplace_back(std::move(transform));
    return Transform(std::move(in), std::move(transforms));
  }

  /// Transforms and returns the WGSL source `in`, transformed using
  /// a transform of type `TRANSFORM`.
  /// @param in the input WGSL source
  /// @param args the TRANSFORM constructor arguments
  /// @return the transformed WGSL output
  template <typename TRANSFORM, typename... ARGS>
  std::string Transform(std::string in, ARGS&&... args) {
    return Transform(std::move(in),
                     std::make_unique<TRANSFORM>(std::forward<ARGS>(args)...));
  }
};

}  // namespace transform
}  // namespace tint

#endif  // SRC_TRANSFORM_TEST_HELPER_H_
