#include <mesh/MeshFlatFaceBoundary.hpp>

#include <mesh/Connectivity.hpp>
#include <mesh/Mesh.hpp>
#include <mesh/MeshFlatNodeBoundary.hpp>

template <size_t Dimension>
MeshFlatFaceBoundary<Dimension>
getMeshFlatFaceBoundary(const Mesh<Connectivity<Dimension>>& mesh, const IBoundaryDescriptor& boundary_descriptor)
{
  for (size_t i_ref_face_list = 0; i_ref_face_list < mesh.connectivity().template numberOfRefItemList<ItemType::face>();
       ++i_ref_face_list) {
    const auto& ref_face_list = mesh.connectivity().template refItemList<ItemType::face>(i_ref_face_list);
    const RefId& ref          = ref_face_list.refId();
    if (ref == boundary_descriptor) {
      MeshFlatNodeBoundary<Dimension> mesh_flat_node_boundary = getMeshFlatNodeBoundary(mesh, boundary_descriptor);

      return MeshFlatFaceBoundary<Dimension>{mesh, ref_face_list, mesh_flat_node_boundary.outgoingNormal()};
    }
  }

  std::ostringstream ost;
  ost << "cannot find surface with name " << rang::fgB::red << boundary_descriptor << rang::style::reset;

  throw NormalError(ost.str());
}

template MeshFlatFaceBoundary<2> getMeshFlatFaceBoundary(const Mesh<Connectivity<2>>&, const IBoundaryDescriptor&);
template MeshFlatFaceBoundary<3> getMeshFlatFaceBoundary(const Mesh<Connectivity<3>>&, const IBoundaryDescriptor&);