// Copyright 2020 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.

#include "src/clone_context.h"

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

#include "gtest/gtest-spi.h"

#include "src/program_builder.h"

namespace tint {
namespace {

struct Node : public Castable<Node, ast::Node> {
  explicit Node(const Source& source, std::string n) : Base(source), name(n) {}

  std::string name;
  Node* a = nullptr;
  Node* b = nullptr;
  Node* c = nullptr;
  std::vector<Node*> vec;

  Node* Clone(CloneContext* ctx) const override {
    auto* out = ctx->dst->create<Node>(name);
    out->a = ctx->Clone(a);
    out->b = ctx->Clone(b);
    out->c = ctx->Clone(c);
    out->vec = ctx->Clone(vec);
    return out;
  }

  bool IsValid() const override { return true; }
  void to_str(const semantic::Info&, std::ostream&, size_t) const override {}
};

struct Replaceable : public Castable<Replaceable, Node> {
  explicit Replaceable(const Source& source, std::string n) : Base(source, n) {}
};
struct Replacement : public Castable<Replacement, Replaceable> {
  explicit Replacement(const Source& source, std::string n) : Base(source, n) {}
};

struct NotANode : public Castable<NotANode, ast::Node> {
  explicit NotANode(const Source& source) : Base(source) {}

  NotANode* Clone(CloneContext* ctx) const override {
    return ctx->dst->create<NotANode>();
  }

  bool IsValid() const override { return true; }
  void to_str(const semantic::Info&, std::ostream&, size_t) const override {}
};

TEST(CloneContext, Clone) {
  ProgramBuilder builder;
  auto* original_root = builder.create<Node>("root");
  original_root->a = builder.create<Node>("a");
  original_root->a->b = builder.create<Node>("a->b");
  original_root->b = builder.create<Node>("b");
  original_root->b->a = original_root->a;  // Aliased
  original_root->b->b = builder.create<Node>("b->b");
  original_root->c = original_root->b;  // Aliased
  Program original(std::move(builder));

  //                          root
  //        ╭──────────────────┼──────────────────╮
  //       (a)                (b)                (c)
  //        N  <──────┐        N  <───────────────┘
  //   ╭────┼────╮    │   ╭────┼────╮
  //  (a)  (b)  (c)   │  (a)  (b)  (c)
  //        N         └───┘    N
  //
  // N: Node

  ProgramBuilder cloned;
  auto* cloned_root = CloneContext(&cloned, &original).Clone(original_root);

  EXPECT_NE(cloned_root->a, nullptr);
  EXPECT_EQ(cloned_root->a->a, nullptr);
  EXPECT_NE(cloned_root->a->b, nullptr);
  EXPECT_EQ(cloned_root->a->c, nullptr);
  EXPECT_NE(cloned_root->b, nullptr);
  EXPECT_NE(cloned_root->b->a, nullptr);
  EXPECT_NE(cloned_root->b->b, nullptr);
  EXPECT_EQ(cloned_root->b->c, nullptr);
  EXPECT_NE(cloned_root->c, nullptr);

  EXPECT_NE(cloned_root->a, original_root->a);
  EXPECT_NE(cloned_root->a->b, original_root->a->b);
  EXPECT_NE(cloned_root->b, original_root->b);
  EXPECT_NE(cloned_root->b->a, original_root->b->a);
  EXPECT_NE(cloned_root->b->b, original_root->b->b);
  EXPECT_NE(cloned_root->c, original_root->c);

  EXPECT_EQ(cloned_root->name, "root");
  EXPECT_EQ(cloned_root->a->name, "a");
  EXPECT_EQ(cloned_root->a->b->name, "a->b");
  EXPECT_EQ(cloned_root->b->name, "b");
  EXPECT_EQ(cloned_root->b->b->name, "b->b");

  EXPECT_EQ(cloned_root->b->a, cloned_root->a);  // Aliased
  EXPECT_EQ(cloned_root->c, cloned_root->b);     // Aliased
}

TEST(CloneContext, CloneWithReplacements) {
  ProgramBuilder builder;
  auto* original_root = builder.create<Node>("root");
  original_root->a = builder.create<Node>("a");
  original_root->a->b = builder.create<Replaceable>("a->b");
  original_root->b = builder.create<Replaceable>("b");
  original_root->b->a = original_root->a;  // Aliased
  original_root->c = original_root->b;     // Aliased
  Program original(std::move(builder));

  //                          root
  //        ╭──────────────────┼──────────────────╮
  //       (a)                (b)                (c)
  //        N  <──────┐        R  <───────────────┘
  //   ╭────┼────╮    │   ╭────┼────╮
  //  (a)  (b)  (c)   │  (a)  (b)  (c)
  //        R         └───┘
  //
  // N: Node
  // R: Replaceable

  ProgramBuilder cloned;
  auto* cloned_root =
      CloneContext(&cloned, &original)
          .ReplaceAll([&](CloneContext* ctx, Replaceable* in) {
            auto* out = cloned.create<Replacement>("replacement:" + in->name);
            out->b = cloned.create<Node>("replacement-child:" + in->name);
            out->c = ctx->Clone(in->a);
            return out;
          })
          .Clone(original_root);

  //                         root
  //        ╭─────────────────┼──────────────────╮
  //       (a)               (b)                (c)
  //        N  <──────┐       R  <───────────────┘
  //   ╭────┼────╮    │  ╭────┼────╮
  //  (a)  (b)  (c)   │ (a)  (b)  (c)
  //        R         │       N    |
  //   ╭────┼────╮    └────────────┘
  //  (a)  (b)  (c)
  //        N
  //
  // N: Node
  // R: Replacement

  EXPECT_NE(cloned_root->a, nullptr);
  EXPECT_EQ(cloned_root->a->a, nullptr);
  EXPECT_NE(cloned_root->a->b, nullptr);     // Replaced
  EXPECT_EQ(cloned_root->a->b->a, nullptr);  // From replacement
  EXPECT_NE(cloned_root->a->b->b, nullptr);  // From replacement
  EXPECT_EQ(cloned_root->a->b->c, nullptr);  // From replacement
  EXPECT_EQ(cloned_root->a->c, nullptr);
  EXPECT_NE(cloned_root->b, nullptr);
  EXPECT_EQ(cloned_root->b->a, nullptr);  // From replacement
  EXPECT_NE(cloned_root->b->b, nullptr);  // From replacement
  EXPECT_NE(cloned_root->b->c, nullptr);  // From replacement
  EXPECT_NE(cloned_root->c, nullptr);

  EXPECT_NE(cloned_root->a, original_root->a);
  EXPECT_NE(cloned_root->a->b, original_root->a->b);
  EXPECT_NE(cloned_root->b, original_root->b);
  EXPECT_NE(cloned_root->b->a, original_root->b->a);
  EXPECT_NE(cloned_root->c, original_root->c);

  EXPECT_EQ(cloned_root->name, "root");
  EXPECT_EQ(cloned_root->a->name, "a");
  EXPECT_EQ(cloned_root->a->b->name, "replacement:a->b");
  EXPECT_EQ(cloned_root->a->b->b->name, "replacement-child:a->b");
  EXPECT_EQ(cloned_root->b->name, "replacement:b");
  EXPECT_EQ(cloned_root->b->b->name, "replacement-child:b");

  EXPECT_EQ(cloned_root->b->c, cloned_root->a);  // Aliased
  EXPECT_EQ(cloned_root->c, cloned_root->b);     // Aliased

  EXPECT_FALSE(cloned_root->a->Is<Replacement>());
  EXPECT_TRUE(cloned_root->a->b->Is<Replacement>());
  EXPECT_FALSE(cloned_root->a->b->b->Is<Replacement>());
  EXPECT_TRUE(cloned_root->b->Is<Replacement>());
  EXPECT_FALSE(cloned_root->b->b->Is<Replacement>());
}

TEST(CloneContext, CloneWithReplace) {
  ProgramBuilder builder;
  auto* original_root = builder.create<Node>("root");
  original_root->a = builder.create<Node>("a");
  original_root->b = builder.create<Node>("b");
  original_root->c = builder.create<Node>("c");
  Program original(std::move(builder));

  //                          root
  //        ╭──────────────────┼──────────────────╮
  //       (a)                (b)                (c)
  //                        Replaced

  ProgramBuilder cloned;
  auto* replacement = cloned.create<Node>("replacement");

  auto* cloned_root = CloneContext(&cloned, &original)
                          .Replace(original_root->b, replacement)
                          .Clone(original_root);

  EXPECT_NE(cloned_root->a, replacement);
  EXPECT_EQ(cloned_root->b, replacement);
  EXPECT_NE(cloned_root->c, replacement);

  EXPECT_EQ(cloned_root->name, "root");
  EXPECT_EQ(cloned_root->a->name, "a");
  EXPECT_EQ(cloned_root->b->name, "replacement");
  EXPECT_EQ(cloned_root->c->name, "c");
}

TEST(CloneContext, CloneWithInsertBefore) {
  ProgramBuilder builder;
  auto* original_root = builder.create<Node>("root");
  original_root->a = builder.create<Node>("a");
  original_root->b = builder.create<Node>("b");
  original_root->c = builder.create<Node>("c");
  original_root->vec = {original_root->a, original_root->b, original_root->c};
  Program original(std::move(builder));

  ProgramBuilder cloned;
  auto* insertion = cloned.create<Node>("insertion");

  auto* cloned_root = CloneContext(&cloned, &original)
                          .InsertBefore(original_root->b, insertion)
                          .Clone(original_root);

  EXPECT_EQ(cloned_root->vec.size(), 4u);
  EXPECT_EQ(cloned_root->vec[0], cloned_root->a);
  EXPECT_EQ(cloned_root->vec[2], cloned_root->b);
  EXPECT_EQ(cloned_root->vec[3], cloned_root->c);

  EXPECT_EQ(cloned_root->name, "root");
  EXPECT_EQ(cloned_root->vec[0]->name, "a");
  EXPECT_EQ(cloned_root->vec[1]->name, "insertion");
  EXPECT_EQ(cloned_root->vec[2]->name, "b");
  EXPECT_EQ(cloned_root->vec[3]->name, "c");
}

TEST(CloneContext, CloneWithReplace_WithNotANode) {
  EXPECT_FATAL_FAILURE(
      {
        ProgramBuilder builder;
        auto* original_root = builder.create<Node>("root");
        original_root->a = builder.create<Node>("a");
        original_root->b = builder.create<Node>("b");
        original_root->c = builder.create<Node>("c");
        Program original(std::move(builder));

        //                          root
        //        ╭──────────────────┼──────────────────╮
        //       (a)                (b)                (c)
        //                        Replaced

        ProgramBuilder cloned;
        auto* replacement = cloned.create<NotANode>();

        CloneContext ctx(&cloned, &original);
        ctx.Replace(original_root->b, replacement);

        ctx.Clone(original_root);
      },
      "internal compiler error");
}

}  // namespace

TINT_INSTANTIATE_CLASS_ID(Node);
TINT_INSTANTIATE_CLASS_ID(Replaceable);
TINT_INSTANTIATE_CLASS_ID(Replacement);
TINT_INSTANTIATE_CLASS_ID(NotANode);

}  // namespace tint
