#include <language/utils/AffectationRegisterForString.hpp>

#include <language/utils/AffectationProcessorBuilder.hpp>
#include <language/utils/BasicAffectationRegistrerFor.hpp>
#include <language/utils/OperatorRepository.hpp>

void
AffectationRegisterForString::_register_eq_op()
{
  OperatorRepository& repository = OperatorRepository::instance();

  auto string_t = ASTNodeDataType::build<ASTNodeDataType::string_t>();

  repository.addAffectation<
    language::eq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::bool_t>(),
                     std::make_shared<AffectationProcessorBuilder<language::eq_op, std::string, bool>>());

  repository.addAffectation<
    language::eq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(),
                     std::make_shared<AffectationProcessorBuilder<language::eq_op, std::string, uint64_t>>());

  repository.addAffectation<
    language::eq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::int_t>(),
                     std::make_shared<AffectationProcessorBuilder<language::eq_op, std::string, int64_t>>());

  repository.addAffectation<
    language::eq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::double_t>(),
                     std::make_shared<AffectationProcessorBuilder<language::eq_op, std::string, double_t>>());

  repository.addAffectation<
    language::eq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::vector_t>(1),
                     std::make_shared<AffectationProcessorBuilder<language::eq_op, std::string, TinyVector<1>>>());

  repository.addAffectation<
    language::eq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::vector_t>(2),
                     std::make_shared<AffectationProcessorBuilder<language::eq_op, std::string, TinyVector<2>>>());

  repository.addAffectation<
    language::eq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::vector_t>(3),
                     std::make_shared<AffectationProcessorBuilder<language::eq_op, std::string, TinyVector<3>>>());

  repository.addAffectation<
    language::eq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, 1),
                     std::make_shared<AffectationProcessorBuilder<language::eq_op, std::string, TinyMatrix<1>>>());

  repository.addAffectation<
    language::eq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, 2),
                     std::make_shared<AffectationProcessorBuilder<language::eq_op, std::string, TinyMatrix<2>>>());

  repository.addAffectation<
    language::eq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, 3),
                     std::make_shared<AffectationProcessorBuilder<language::eq_op, std::string, TinyMatrix<3>>>());

  repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(string_t),
                                             ASTNodeDataType::build<ASTNodeDataType::bool_t>(),
                                             std::make_shared<AffectationToTupleProcessorBuilder<std::string>>());

  repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(string_t),
                                             ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(),
                                             std::make_shared<AffectationToTupleProcessorBuilder<std::string>>());

  repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(string_t),
                                             ASTNodeDataType::build<ASTNodeDataType::int_t>(),
                                             std::make_shared<AffectationToTupleProcessorBuilder<std::string>>());

  repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(string_t),
                                             ASTNodeDataType::build<ASTNodeDataType::double_t>(),
                                             std::make_shared<AffectationToTupleProcessorBuilder<std::string>>());

  repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(string_t),
                                             ASTNodeDataType::build<ASTNodeDataType::vector_t>(1),
                                             std::make_shared<AffectationToTupleProcessorBuilder<std::string>>());

  repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(string_t),
                                             ASTNodeDataType::build<ASTNodeDataType::vector_t>(2),
                                             std::make_shared<AffectationToTupleProcessorBuilder<std::string>>());

  repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(string_t),
                                             ASTNodeDataType::build<ASTNodeDataType::vector_t>(3),
                                             std::make_shared<AffectationToTupleProcessorBuilder<std::string>>());

  repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(string_t),
                                             ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, 1),
                                             std::make_shared<AffectationToTupleProcessorBuilder<std::string>>());

  repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(string_t),
                                             ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, 2),
                                             std::make_shared<AffectationToTupleProcessorBuilder<std::string>>());

  repository.addAffectation<language::eq_op>(ASTNodeDataType::build<ASTNodeDataType::tuple_t>(string_t),
                                             ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, 3),
                                             std::make_shared<AffectationToTupleProcessorBuilder<std::string>>());
}

void
AffectationRegisterForString::_register_pluseq_op()
{
  OperatorRepository& repository = OperatorRepository::instance();

  auto string_t = ASTNodeDataType::build<ASTNodeDataType::string_t>();

  repository.addAffectation<language::pluseq_op>(string_t, string_t,
                                                 std::make_shared<AffectationProcessorBuilder<
                                                   language::pluseq_op, std::string, std::string>>());

  repository.addAffectation<
    language::pluseq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::bool_t>(),
                         std::make_shared<AffectationProcessorBuilder<language::pluseq_op, std::string, bool>>());

  repository.addAffectation<
    language::pluseq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::unsigned_int_t>(),
                         std::make_shared<AffectationProcessorBuilder<language::pluseq_op, std::string, uint64_t>>());

  repository.addAffectation<
    language::pluseq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::int_t>(),
                         std::make_shared<AffectationProcessorBuilder<language::pluseq_op, std::string, int64_t>>());

  repository.addAffectation<
    language::pluseq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::double_t>(),
                         std::make_shared<AffectationProcessorBuilder<language::pluseq_op, std::string, double>>());

  repository.addAffectation<language::pluseq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::vector_t>(1),
                                                 std::make_shared<AffectationProcessorBuilder<
                                                   language::pluseq_op, std::string, TinyVector<1>>>());

  repository.addAffectation<language::pluseq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::vector_t>(2),
                                                 std::make_shared<AffectationProcessorBuilder<
                                                   language::pluseq_op, std::string, TinyVector<2>>>());

  repository.addAffectation<language::pluseq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::vector_t>(3),
                                                 std::make_shared<AffectationProcessorBuilder<
                                                   language::pluseq_op, std::string, TinyVector<3>>>());

  repository.addAffectation<language::pluseq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::matrix_t>(1, 1),
                                                 std::make_shared<AffectationProcessorBuilder<
                                                   language::pluseq_op, std::string, TinyMatrix<1>>>());

  repository.addAffectation<language::pluseq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::matrix_t>(2, 2),
                                                 std::make_shared<AffectationProcessorBuilder<
                                                   language::pluseq_op, std::string, TinyMatrix<2>>>());

  repository.addAffectation<language::pluseq_op>(string_t, ASTNodeDataType::build<ASTNodeDataType::matrix_t>(3, 3),
                                                 std::make_shared<AffectationProcessorBuilder<
                                                   language::pluseq_op, std::string, TinyMatrix<3>>>());
}

AffectationRegisterForString::AffectationRegisterForString()
{
  BasicAffectationRegisterFor<std::string>{};
  this->_register_eq_op();
  this->_register_pluseq_op();
}