#ifndef MESH_FLAT_FACE_BOUNDARY_HPP
#define MESH_FLAT_FACE_BOUNDARY_HPP

#include <mesh/MeshFaceBoundary.hpp>

template <size_t Dimension>
class MeshFlatFaceBoundary final : public MeshFaceBoundary<Dimension>   // clazy:exclude=copyable-polymorphic
{
 public:
  using Rd = TinyVector<Dimension, double>;

 private:
  const Rd m_outgoing_normal;

 public:
  const Rd&
  outgoingNormal() const
  {
    return m_outgoing_normal;
  }

  MeshFlatFaceBoundary& operator=(const MeshFlatFaceBoundary&) = default;
  MeshFlatFaceBoundary& operator=(MeshFlatFaceBoundary&&) = default;

  template <size_t MeshDimension>
  friend MeshFlatFaceBoundary<MeshDimension> getMeshFlatFaceBoundary(const Mesh<Connectivity<MeshDimension>>& mesh,
                                                                     const IBoundaryDescriptor& boundary_descriptor);

 private:
  template <typename MeshType>
  MeshFlatFaceBoundary(const MeshType& mesh, const RefFaceList& ref_face_list, const Rd& outgoing_normal)
    : MeshFaceBoundary<Dimension>(mesh, ref_face_list), m_outgoing_normal(outgoing_normal)
  {}

 public:
  MeshFlatFaceBoundary()                            = default;
  MeshFlatFaceBoundary(const MeshFlatFaceBoundary&) = default;
  MeshFlatFaceBoundary(MeshFlatFaceBoundary&&)      = default;
  ~MeshFlatFaceBoundary()                           = default;
};

template <size_t Dimension>
MeshFlatFaceBoundary<Dimension> getMeshFlatFaceBoundary(const Mesh<Connectivity<Dimension>>& mesh,
                                                        const IBoundaryDescriptor& boundary_descriptor);

#endif   // MESH_FLAT_FACE_BOUNDARY_HPP