#include <MeshDataBaseForTests.hpp>
#include <mesh/CartesianMeshBuilder.hpp>
#include <mesh/Connectivity.hpp>
#include <utils/PugsAssert.hpp>

const MeshDataBaseForTests* MeshDataBaseForTests::m_instance = nullptr;

MeshDataBaseForTests::MeshDataBaseForTests()
{
  m_cartesian_1d_mesh = CartesianMeshBuilder{TinyVector<1>{-1}, TinyVector<1>{3}, TinyVector<1, size_t>{23}}.mesh();

  m_cartesian_2d_mesh =
    CartesianMeshBuilder{TinyVector<2>{0, -1}, TinyVector<2>{3, 2}, TinyVector<2, size_t>{6, 7}}.mesh();

  m_cartesian_3d_mesh =
    CartesianMeshBuilder{TinyVector<3>{0, 1, 0}, TinyVector<3>{2, -1, 3}, TinyVector<3, size_t>{6, 7, 4}}.mesh();
}

const MeshDataBaseForTests&
MeshDataBaseForTests::get()
{
  return *m_instance;
}

void
MeshDataBaseForTests::create()
{
  Assert(m_instance == nullptr);
  m_instance = new MeshDataBaseForTests();
}

void
MeshDataBaseForTests::destroy()
{
  Assert(m_instance != nullptr);
  delete m_instance;
  m_instance = nullptr;
}

template <size_t Dimension>
const Mesh<Connectivity<Dimension>>&
MeshDataBaseForTests::cartesianMesh() const
{
  if constexpr (Dimension == 1) {
    return dynamic_cast<const Mesh<Connectivity<Dimension>>&>(*m_cartesian_1d_mesh);
  } else if constexpr (Dimension == 2) {
    return dynamic_cast<const Mesh<Connectivity<Dimension>>&>(*m_cartesian_2d_mesh);
  } else if constexpr (Dimension == 3) {
    return dynamic_cast<const Mesh<Connectivity<Dimension>>&>(*m_cartesian_3d_mesh);
  }
}

template const Mesh<Connectivity<1>>& MeshDataBaseForTests::cartesianMesh<1>() const;
template const Mesh<Connectivity<2>>& MeshDataBaseForTests::cartesianMesh<2>() const;
template const Mesh<Connectivity<3>>& MeshDataBaseForTests::cartesianMesh<3>() const;