#ifndef BSSN_CUDA_OPS_H
#define BSSN_CUDA_OPS_H

int bssn_cuda_enforce_ga(int *ex,
                         double *dxx, double *gxy, double *gxz,
                         double *dyy, double *gyz, double *dzz,
                         double *Axx, double *Axy, double *Axz,
                         double *Ayy, double *Ayz, double *Azz);

int bssn_cuda_rk4_boundary_var(int *ex, double dT,
                               const double *X, const double *Y, const double *Z,
                               double xmin, double ymin, double zmin,
                               double xmax, double ymax, double zmax,
                               const double *state0,
                               const double *phi_field,
                               const double *lap_field,
                               const double *boundary_src,
                               double *stage_data,
                               double *rhs_accum,
                               double propspeed,
                               const double SoA[3],
                               int symmetry,
                               int lev,
                               int rk_stage,
                               bool download_to_host = true);

int bssn_cuda_lowerbound(int *ex, double *chi, double tinny, bool download_to_host = true);
int bssn_cuda_download_buffer(int *ex, double *host_ptr);
void bssn_cuda_release_rk4_caches();
void bssn_cuda_release_interp_caches();

int bssn_cuda_prolong3_pack(int wei,
                            const double *llbc, const double *uubc, const int *extc, const double *func,
                            const double *llbf, const double *uubf, const int *extf, double *funf,
                            const double *llbp, const double *uubp,
                            const double *SoA, int symmetry);

int bssn_cuda_restrict3_pack(int wei,
                             const double *llbc, const double *uubc, const int *extc, double *func,
                             const double *llbf, const double *uubf, const int *extf, const double *funf,
                             const double *llbr, const double *uubr,
                             const double *SoA, int symmetry);

int bssn_cuda_interp_points_batch(const int *ex,
                                  const double *X, const double *Y, const double *Z,
                                  const double *const *fields,
                                  const double *soa_flat,
                                  int num_var,
                                  const double *px, const double *py, const double *pz,
                                  int num_points,
                                  int ordn,
                                  int symmetry,
                                  double *out);

#endif
