# cython: language_level=3
"""C declarations for the subset of HYPRE / hypredrive used by the Python binding.

We deliberately keep this surface narrow: only the public entry points needed
to drive a single end-to-end solve from Python. Anything more is pulled in
behind explicit feature work.
"""

from libc.stddef cimport size_t
from libc.stdint cimport int64_t, uint32_t


cdef extern from "HYPRE.h" nogil:
    ctypedef void *HYPRE_Vector
    ctypedef void *HYPRE_Matrix


cdef extern from "HYPREDRV.h" nogil:
    ctypedef struct hypredrv_struct
    ctypedef hypredrv_struct *HYPREDRV_t

    uint32_t HYPREDRV_Initialize()
    uint32_t HYPREDRV_Finalize()

    uint32_t HYPREDRV_Destroy(HYPREDRV_t *hypredrv_ptr)
    uint32_t HYPREDRV_SetLibraryMode(HYPREDRV_t hypredrv)

    uint32_t HYPREDRV_InputArgsParse(int argc, char **argv,
                                     HYPREDRV_t hypredrv)

    uint32_t HYPREDRV_LinearSystemSetInitialGuess(HYPREDRV_t hypredrv,
                                                  HYPRE_Vector vec)
    uint32_t HYPREDRV_LinearSystemResetInitialGuess(HYPREDRV_t hypredrv)
    uint32_t HYPREDRV_LinearSystemSetDofmap(HYPREDRV_t hypredrv,
                                            int size,
                                            const int *dofmap)
    uint32_t HYPREDRV_LinearSystemGetSolutionNorm(HYPREDRV_t hypredrv,
                                                  const char *norm_type,
                                                  double *norm)

    uint32_t HYPREDRV_LinearSolverCreate(HYPREDRV_t hypredrv)
    uint32_t HYPREDRV_LinearSolverSetup(HYPREDRV_t hypredrv)
    uint32_t HYPREDRV_LinearSolverApply(HYPREDRV_t hypredrv)
    uint32_t HYPREDRV_LinearSolverDestroy(HYPREDRV_t hypredrv)
    uint32_t HYPREDRV_LinearSolverGetNumIter(HYPREDRV_t hypredrv, int *iters)
    uint32_t HYPREDRV_LinearSolverGetConverged(HYPREDRV_t hypredrv,
                                               int *converged)
    uint32_t HYPREDRV_LinearSolverGetFinalRelativeResidualNorm(
        HYPREDRV_t hypredrv, double *norm)
    uint32_t HYPREDRV_LinearSolverGetSetupTime(HYPREDRV_t hypredrv,
                                               double *seconds)
    uint32_t HYPREDRV_LinearSolverGetSolveTime(HYPREDRV_t hypredrv,
                                               double *seconds)

    uint32_t HYPREDRV_AnnotateBegin(HYPREDRV_t hypredrv, const char *name,
                                    int id)
    uint32_t HYPREDRV_AnnotateEnd(HYPREDRV_t hypredrv, const char *name,
                                  int id)

    void HYPREDRV_ErrorCodeDescribe(uint32_t error_code)


cdef extern from "HYPREDRV_python.h" nogil:
    size_t HYPREDRV_PythonIndexSize()
    size_t HYPREDRV_PythonRealSize()
    size_t HYPREDRV_PythonSolutionEntrySize()
    uint32_t HYPREDRV_PythonMPIInitialize()
    uint32_t HYPREDRV_PythonMPIFinalize()

    uint32_t HYPREDRV_PythonCreateWithSelf(HYPREDRV_t *hypredrv_ptr)
    uint32_t HYPREDRV_PythonCreateFromFortranComm(
        int fortran_comm,
        HYPREDRV_t *hypredrv_ptr)

    uint32_t HYPREDRV_PythonSetMatrixFromCSR(
        HYPREDRV_t hypredrv,
        int64_t row_start,
        int64_t row_end,
        const void *indptr,
        const void *col_indices,
        const void *data)

    uint32_t HYPREDRV_PythonSetRHSFromArray(
        HYPREDRV_t hypredrv,
        int64_t row_start,
        int64_t row_end,
        const void *values)

    uint32_t HYPREDRV_PythonGetSolutionValues(
        HYPREDRV_t hypredrv,
        const void **sol_data,
        size_t *sol_length)
