#include <gtest/gtest.h>
#include <torch/torch.h>
#include <algorithm>
#include <memory>
#include <vector>

#include <test/cpp/api/support.h>

using namespace torch::nn;
using namespace torch::test;

struct ModuleDictTest : torch::test::SeedingFixture {};

TEST_F(ModuleDictTest, ConstructsFromList) {
  struct M : Module {
    explicit M(int value_) : value(value_) {}
    int value;
  };

  std::vector<std::pair<std::string, std::shared_ptr<Module>>> list = {
      {"module_1", std::make_shared<M>(1)},
      {"module_2", std::make_shared<M>(2)},
      {"module_3", std::make_shared<M>(3)}};
  ModuleDict dict(list);
  ASSERT_EQ(dict->size(), 3);
}

TEST_F(ModuleDictTest, ConstructsFromordereddict) {
  struct M : Module {
    explicit M(int value_) : value(value_) {}
    int value;
  };

  torch::OrderedDict<std::string, std::shared_ptr<Module>> ordereddict = {
      {"module_1", std::make_shared<M>(1)},
      {"module_2", std::make_shared<M>(2)},
      {"module_3", std::make_shared<M>(3)},
  };
  ModuleDict dict(ordereddict);
  ASSERT_EQ(dict->size(), 3);
}

TEST_F(ModuleDictTest, UpdatePopClearContains) {
  struct M : Module {
    explicit M(int value_) : value(value_) {}
    int value;
  };

  ModuleDict dict;
  ASSERT_TRUE(dict->empty());
  // Update by List
  std::vector<std::pair<std::string, std::shared_ptr<Module>>> list1 = {
      {"module_1", std::make_shared<M>(1)}};
  dict->update(list1);
  ASSERT_EQ(dict->size(), 1);
  ASSERT_TRUE(dict->contains("module_1"));
  // Update by OrderedDict
  torch::OrderedDict<std::string, std::shared_ptr<Module>> ordereddict = {
      {"module_2", std::make_shared<M>(2)}};
  dict->update(ordereddict);
  ASSERT_EQ(dict->size(), 2);
  ASSERT_TRUE(dict->contains("module_2"));
  // Update by another ModuleDict
  std::vector<std::pair<std::string, std::shared_ptr<Module>>> list2 = {
      {"module_3", std::make_shared<M>(3)}};
  ModuleDict updatedict(list2);
  dict->update(*updatedict);
  ASSERT_EQ(dict->size(), 3);
  ASSERT_TRUE(dict->contains("module_3"));
  // Pop
  dict->pop("module_1");
  ASSERT_EQ(dict->size(), 2);
  // Pop unexist
  ASSERT_THROWS_WITH(dict->pop("module_4"), " 'module_4' is not defined");
  // Clear
  dict->clear();
  ASSERT_EQ(dict->size(), 0);
}

TEST_F(ModuleDictTest, UpdateExist) {
  struct M : Module {
    explicit M(int value_) : value(value_) {}
    int value;
  };
  std::vector<std::pair<std::string, std::shared_ptr<Module>>> list1 = {
      {"module_1", std::make_shared<M>(1)},
      {"module_2", std::make_shared<M>(2)}};
  ModuleDict dict(list1);
  ASSERT_EQ(dict->at<M>("module_2").value, 2);
  // Update by list
  std::vector<std::pair<std::string, std::shared_ptr<Module>>> list2 = {
      {"module_2", std::make_shared<M>(0)},
      {"module_3", std::make_shared<M>(3)}};
  dict->update(list2);
  ASSERT_EQ(dict->size(), 3);
  ASSERT_EQ(dict->at<M>("module_2").value, 0);
  // Update by ordereddict
  torch::OrderedDict<std::string, std::shared_ptr<Module>> ordereddict = {
      {"module_3", std::make_shared<M>(0)},
      {"module_4", std::make_shared<M>(4)}};
  dict->update(ordereddict);
  ASSERT_EQ(dict->size(), 4);
  ASSERT_EQ(dict->at<M>("module_3").value, 0);
  // Update by ModuleDict
  std::vector<std::pair<std::string, std::shared_ptr<Module>>> list3 = {
      {"module_4", std::make_shared<M>(0)},
      {"module_1", std::make_shared<M>(0)}};
  ModuleDict dict2(list3);
  dict->update(*dict2);
  ASSERT_EQ(dict->size(), 4);
  ASSERT_EQ(dict->at<M>("module_1").value, 0);
  ASSERT_EQ(dict->at<M>("module_4").value, 0);
}

TEST_F(ModuleDictTest, Keys) {
  struct M : Module {
    explicit M(int value_) : value(value_) {}
    int value;
  };

  torch::OrderedDict<std::string, std::shared_ptr<Module>> ordereddict = {
      {"linear", Linear(10, 3).ptr()},
      {"conv", Conv2d(1, 2, 3).ptr()},
      {"dropout", Dropout(0.5).ptr()},
  };
  ModuleDict dict(ordereddict);
  const auto& keys = dict->keys();
  std::vector<std::string> expected{"linear", "conv", "dropout"};
  ASSERT_EQ(keys, expected);
  ASSERT_THROWS_WITH(dict["batch"], " 'batch' is not defined");

  ASSERT_TRUE(dict["linear"]->as<Linear>());
  ASSERT_TRUE(dict["conv"]->as<Conv2d>());
  ASSERT_TRUE(dict["dropout"]->as<Dropout>());
}

TEST_F(ModuleDictTest, Values) {
  struct M : Module {
    explicit M(int value_) : value(value_) {}
    int value;
  };

  torch::OrderedDict<std::string, std::shared_ptr<Module>> ordereddict = {
      {"module_1", std::make_shared<M>(1)},
      {"module_2", std::make_shared<M>(2)},
  };
  ModuleDict dict(ordereddict);
  const auto& values = dict->values();
  const auto& expected = ordereddict.values();
  ASSERT_EQ(values, expected);
  ASSERT_TRUE(std::equal(
      dict->begin(),
      dict->end(),
      ordereddict.begin(),
      [](const auto& lhs, const auto& rhs) {
        return lhs.value().get() == rhs.value().get();
      }));
}

TEST_F(ModuleDictTest, SanityCheckForHoldingStandardModules) {
  torch::OrderedDict<std::string, std::shared_ptr<Module>> ordereddict = {
      {"linear", Linear(10, 3).ptr()},
      {"conv", Conv2d(1, 2, 3).ptr()},
      {"dropout", Dropout(0.5).ptr()},
      {"batch", BatchNorm2d(5).ptr()},
      {"embedding", Embedding(4, 10).ptr()},
      {"lstm", LSTM(4, 5).ptr()}};
  ModuleDict dict(ordereddict);
}

TEST_F(ModuleDictTest, HasReferenceSemantics) {
  torch::OrderedDict<std::string, std::shared_ptr<Module>> ordereddict = {
      {"linear1", Linear(2, 3).ptr()},
      {"linear2", Linear(3, 4).ptr()},
      {"linear3", Linear(4, 5).ptr()},
  };
  ModuleDict first(ordereddict);
  ModuleDict second(ordereddict);

  ASSERT_EQ(first->size(), second->size());
  ASSERT_TRUE(std::equal(
      first->begin(),
      first->end(),
      second->begin(),
      [](const auto& lhs, const auto& rhs) {
        return lhs.value().get() == rhs.value().get();
      }));
}

void iscloneable_helper(torch::Device device) {
  torch::OrderedDict<std::string, std::shared_ptr<Module>> ordereddict = {
      {"linear", Linear(2, 3).ptr()},
      {"relu", Functional(torch::relu).ptr()},
      {"batch", BatchNorm1d(3).ptr()},
  };
  ModuleDict dict(ordereddict);
  dict->to(device);
  ModuleDict clone =
      std::dynamic_pointer_cast<ModuleDictImpl>(dict->clone(device));
  ASSERT_EQ(dict->size(), clone->size());

  for (auto it = dict->begin(), it_c = clone->begin(); it != dict->end();
       ++it, ++it_c) {
    // The key should be same
    ASSERT_EQ(it->key(), it_c->key());
    // The modules should be the same kind (type).
    ASSERT_EQ(it->value()->name(), it_c->value()->name());
    // But not pointer-equal (distinct objects).
    ASSERT_NE(it->value(), it_c->value());
  }

  // Verify that the clone is deep, i.e. parameters of modules are cloned too.
  torch::NoGradGuard no_grad;

  auto params1 = dict->named_parameters();
  auto params2 = clone->named_parameters();
  ASSERT_EQ(params1.size(), params2.size());
  for (auto& param : params1) {
    ASSERT_FALSE(pointer_equal(param.value(), params2[param.key()]));
    ASSERT_EQ(param->device(), params2[param.key()].device());
    ASSERT_TRUE(param->allclose(params2[param.key()]));
    param->add_(2);
  }
  for (auto& param : params1) {
    ASSERT_FALSE(param->allclose(params2[param.key()]));
  }
}

TEST_F(ModuleDictTest, IsCloneable) {
  iscloneable_helper(torch::kCPU);
}

TEST_F(ModuleDictTest, IsCloneable_CUDA) {
  iscloneable_helper({torch::kCUDA, 0});
}

TEST_F(ModuleDictTest, RegistersElementsAsSubmodules) {
  torch::OrderedDict<std::string, std::shared_ptr<Module>> ordereddict1 = {
      {"linear", Linear(10, 3).ptr()},
      {"conv", Conv2d(1, 2, 3).ptr()},
      {"test", Dropout(0.5).ptr()},
  };
  ModuleDict dict(ordereddict1);

  auto modules = dict->children();
  ASSERT_TRUE(modules[0]->as<Linear>());
  ASSERT_TRUE(modules[1]->as<Conv2d>());
  ASSERT_TRUE(modules[2]->as<Dropout>());

  // Update Existing
  torch::OrderedDict<std::string, std::shared_ptr<Module>> ordereddict2 = {
      {"lstm", LSTM(4, 5).ptr()}, {"test", BatchNorm2d(5).ptr()}};
  dict->update(ordereddict2);

  modules = dict->children();
  ASSERT_TRUE(modules[0]->as<Linear>());
  ASSERT_TRUE(modules[1]->as<Conv2d>());
  // Keep Order
  ASSERT_TRUE(modules[2]->as<BatchNorm2d>());
  ASSERT_TRUE(modules[3]->as<LSTM>());
}

TEST_F(ModuleDictTest, CloneToDevice_CUDA) {
  torch::OrderedDict<std::string, std::shared_ptr<Module>> ordereddict = {
      {"linear", Linear(2, 3).ptr()},
      {"relu", Functional(torch::relu).ptr()},
      {"batch", BatchNorm1d(3).ptr()},
  };
  ModuleDict dict(ordereddict);
  torch::Device device(torch::kCUDA, 0);
  ModuleDict clone =
      std::dynamic_pointer_cast<ModuleDictImpl>(dict->clone(device));
  for (const auto& p : clone->parameters()) {
    ASSERT_EQ(p.device(), device);
  }
  for (const auto& b : clone->buffers()) {
    ASSERT_EQ(b.device(), device);
  }
}

TEST_F(ModuleDictTest, PrettyPrintModuleDict) {
  torch::OrderedDict<std::string, std::shared_ptr<Module>> ordereddict = {
      {"linear", Linear(10, 3).ptr()},
      {"conv", Conv2d(1, 2, 3).ptr()},
      {"dropout", Dropout(0.5).ptr()},
      {"batch", BatchNorm2d(5).ptr()},
      {"embedding", Embedding(4, 10).ptr()},
      {"lstm", LSTM(4, 5).ptr()}};
  ModuleDict dict(ordereddict);

  ASSERT_EQ(
      c10::str(dict),
      "torch::nn::ModuleDict(\n"
      "  (linear): torch::nn::Linear(in_features=10, out_features=3, bias=true)\n"
      "  (conv): torch::nn::Conv2d(1, 2, kernel_size=[3, 3], stride=[1, 1])\n"
      "  (dropout): torch::nn::Dropout(p=0.5, inplace=false)\n"
      "  (batch): torch::nn::BatchNorm2d(5, eps=1e-05, momentum=0.1, affine=true, track_running_stats=true)\n"
      "  (embedding): torch::nn::Embedding(num_embeddings=4, embedding_dim=10)\n"
      "  (lstm): torch::nn::LSTM(input_size=4, hidden_size=5, num_layers=1, bias=true, batch_first=false, dropout=0, bidirectional=false)\n"
      ")");
}
