#ifndef ACOUSTIC_SOLVER_TEST_HPP
#define ACOUSTIC_SOLVER_TEST_HPP

#include <Kokkos_Core.hpp>

#include <TinyVector.hpp>

class AcousticSolverTest 
{
private:
  constexpr static size_t dimension = 1;
  
  inline const Kokkos::View<const double*>
  computeRhoCj(const Kokkos::View<const double*>& rhoj,
	       const Kokkos::View<const double*>& cj);

  inline const Kokkos::View<const double*[2]>
  computeAjr(const Kokkos::View<const double*>& rhocj,
	     const Kokkos::View<const double*[2]>& Cjr);

  inline const Kokkos::View<const double*>
  computeAr(const Kokkos::View<const double*[2]>& Ajr,
	    const Kokkos::View<const int*[2]>& node_cells,
	    const Kokkos::View<const int*[2]>& node_cell_local_node,
	    const Kokkos::View<const int*>& node_nb_cells);

  inline const Kokkos::View<const double*>
  computeBr(const Kokkos::View<const double*[2]>& Ajr,
	    const Kokkos::View<const double*[2]>& Cjr,
	    const Kokkos::View<const double*>& uj,
	    const Kokkos::View<const double*>& pj,
	    const Kokkos::View<const int*[2]>& node_cells,
	    const Kokkos::View<const int*[2]>& node_cell_local_node,
	    const Kokkos::View<const int*>& node_nb_cells);

  Kokkos::View<double*>
  computeUr(const Kokkos::View<const double*>& Ar,
	    const Kokkos::View<const double*>& br);

  Kokkos::View<double*[2]>
  computeFjr(const Kokkos::View<const double*[2]>& Ajr,
	     const Kokkos::View<const double*>& ur,
	     const Kokkos::View<const double*[2]>& Cjr,
	     const Kokkos::View<const double*>& uj,
	     const Kokkos::View<const double*>& pj,
	     const Kokkos::View<const int*[2]>& cell_nodes);

  void inverse(const Kokkos::View<const double*>& x,
	       Kokkos::View<double*>& inv_x) const;

  inline double acoustic_dt(const Kokkos::View<const double*>& Vj,
			    const Kokkos::View<const double*>& cj) const;

  inline void computeExplicitFluxes(const Kokkos::View<const double*>& xr,
				    const Kokkos::View<const double*>& xj,
				    const Kokkos::View<const double*>& rhoj,
				    const Kokkos::View<const double*>& uj,
				    const Kokkos::View<const double*>& pj,
				    const Kokkos::View<const double*>& cj,
				    const Kokkos::View<const double*>& Vj,
				    const Kokkos::View<const double*[2]>& Cjr,
				    const Kokkos::View<const int*[2]>& cell_nodes,
				    const Kokkos::View<const int*[2]>& node_cells,
				    const Kokkos::View<const int*>& node_nb_cells,
				    const Kokkos::View<const int*[2]>& node_cell_local_node,
				    Kokkos::View<double*>& ur,
				    Kokkos::View<double*[2]>& Fjr);

  struct ReduceMin;

  const size_t m_nj;
  const size_t m_nr;

  Kokkos::View<double*> m_br;
  Kokkos::View<double*[2]> m_Ajr;
  Kokkos::View<double*> m_Ar;
  Kokkos::View<double*> m_inv_Ar;
  Kokkos::View<double*[2]> m_Fjr;
  Kokkos::View<double*> m_ur;
  Kokkos::View<double*> m_rhocj;
  Kokkos::View<double*> m_Vj_over_cj;


public:
  AcousticSolverTest(const long int& nj);
};

#endif // ACOUSTIC_SOLVER_TEST_HPP