#ifndef SPEC_TASKS_HH
#define SPEC_TASKS_HH

#include "../mesh.hh"
#include "../types.hh"

#include <cstddef>

namespace spec::tasks {

template<std::size_t D, dm::domain DM>
struct printer {
};

template<dm::domain DM>
struct printer<1, DM> {
  static void print(flecsi::exec::cpu,
    typename mesh<1>::template accessor<ro> m,
    field<double>::accessor<ro, ro> q_a,
    std::string const & label) noexcept {
    auto r = m.template mdcolex<is::cells>(q_a);
    std::stringstream ss;
    ss << label << std::endl;
    for(auto i : m.cells<ax::x, DM>()) {
      ss << r(i) << " ";
    } // for
    ss << std::endl;
    flog(info) << ss.str();
  } // print
}; // struct printer<1>

template<dm::domain DM>
struct printer<2, DM> {
  static void print(flecsi::exec::cpu,
    typename mesh<2>::template accessor<ro> m,
    field<double>::accessor<ro, ro> q_a,
    std::string const & label) noexcept {
    auto r = m.template mdcolex<is::cells>(q_a);
    std::stringstream ss;
    ss << label << std::endl;
    for(auto j : m.cells<ax::y, DM>()) {
      for(auto i : m.cells<ax::x, DM>()) {
        ss << r(i, j) << " ";
      } // for
      ss << std::endl;
    } // for
    ss << std::endl;
    flog(info) << ss.str();
  } // print
}; // struct printer<2>

template<dm::domain DM>
struct printer<3, DM> {
  static void print(flecsi::exec::cpu,
    typename mesh<3>::template accessor<ro> m,
    field<double>::accessor<ro, ro> q_a,
    std::string const & label) noexcept {
    auto r = m.template mdcolex<is::cells>(q_a);
    std::stringstream ss;
    ss << label << std::endl;
    for(auto k : m.cells<ax::z, DM>()) {
      for(auto j : m.cells<ax::y, DM>()) {
        for(auto i : m.cells<ax::x, DM>()) {
          ss << r(i, j, k) << " ";
        } // for
        ss << std::endl;
      } // for
      ss << std::endl;
    } // for
    ss << std::endl;
    flog(info) << ss.str();
  } // print
}; // struct printer<3>

} // namespace spec::tasks

#endif // SPEC_TASKS_HH
