module sirius_mode
  use iso_c_binding, only: c_ptr
  use f_refcnts, only: f_reference_counter

  implicit none

  private

  type, public :: SIRIUS_restart_objects
     type(f_reference_counter) :: refcnt
     type(c_ptr) :: ctx
  end type SIRIUS_restart_objects

  public :: nullify_SIRIUS_restart_objects, free_SIRIUS_restart_objects, init_SIRIUS_restart_objects
  public :: sirius_ground_state

contains

  pure subroutine nullify_SIRIUS_restart_objects(sirius_rst)
    use iso_c_binding, only: c_null_ptr
    use f_refcnts
    implicit none
    type(SIRIUS_restart_objects), intent(out) :: sirius_rst
    call nullify_f_ref(sirius_rst%refcnt)
    sirius_rst%ctx = c_null_ptr
  end subroutine nullify_SIRIUS_restart_objects

  subroutine free_SIRIUS_restart_objects(sirius_rst)
    use f_refcnts
    use iso_c_binding, only: c_associated
    implicit none
    type(SIRIUS_restart_objects), intent(inout) :: sirius_rst
    !check if the object can be freed
    if (f_ref_count(sirius_rst%refcnt) >= 0) call f_ref_free(sirius_rst%refcnt)
  end subroutine free_SIRIUS_restart_objects

  subroutine init_SIRIUS_restart_objects(sirius_rst, inputs, atoms, mpi_comm)
    use f_refcnts
    use module_input_keys
    use module_atoms
    implicit none
    type(SIRIUS_restart_objects), intent(inout) :: sirius_rst
    type(input_variables), intent(in) :: inputs
    type(atoms_data), intent(in) :: atoms
    integer, intent(in) :: mpi_comm

    sirius_rst%refcnt = f_ref_new('sirius_rst')
  end subroutine init_SIRIUS_restart_objects

  subroutine sirius_ground_state(sirius_rst, energy, forces, infocode)
    use dictionaries, only: f_err_throw
    use module_precisions
    type(SIRIUS_restart_objects), intent(inout) :: sirius_rst
    real(gp), intent(out) :: energy
    real(gp), dimension(:,:), intent(out) :: forces
    integer, intent(inout) :: infocode

    call f_err_throw("SIRIUS is not compiled", err_name = 'BIGDFT_RUNTIME_ERROR')
  END SUBROUTINE sirius_ground_state

end module sirius_mode
