module cubeio_timing
  use gkernel_types
  use gkernel_interfaces
  use cubetools_parameters
  use cubetools_format
  use cubeio_messaging
  !---------------------------------------------------------------------
  ! Module to manage timing of I/O operations of one cube
  !---------------------------------------------------------------------
  !
  type cubeio_time_t
    type(cputime_t) :: total  ! Total execution time
    type(cputime_t) :: read   ! Reading data from disk
    type(cputime_t) :: writ   ! Writing data to disk
  contains
    procedure :: init     => cubeio_timing_init
    procedure :: feedback => cubeio_timing_feedback
  end type cubeio_time_t

  public :: cubeio_time_t
  private

contains

  subroutine cubeio_timing_init(time,error)
    !---------------------------------------------------------------------
    !---------------------------------------------------------------------
    class(cubeio_time_t), intent(inout) :: time
    logical,              intent(inout) :: error
    !
    call gag_cputime_init(time%total)
    call gag_cputime_init(time%read)
    call gag_cputime_init(time%writ)
  end subroutine cubeio_timing_init

  subroutine cubeio_timing_feedback(time,siz)
    !---------------------------------------------------------------------
    !---------------------------------------------------------------------
    class(cubeio_time_t), intent(in) :: time
    integer(kind=data_k), intent(in) :: siz
    !
    character(len=*), parameter :: rname='TIMING>FEEDBACK'
    character(len=mess_l) :: mess
    !
    print *,''
    !
  !!$ *** JP filename is not there anymore...
  !!$  write(mess,'(A,T45,A)')  trim(cub%head%gen%filename),cubetools_format_memsize(siz)
    write(mess,'(T45,A)') cubetools_format_memsize(siz)
    call cubeio_message(seve%r,rname,mess)
    !
    call print_it('Lifetime:',                     time%total%diff%elapsed,siz,.false.)
    call print_it('Time elapsed reading the cube:',time%read%curr%elapsed, siz,.true.)
    call print_it('Time elapsed writing the cube:',time%writ%curr%elapsed, siz,.true.)
    !
  end subroutine cubeio_timing_feedback

  subroutine print_it(prefix,elapsed,siz,dorate)
    character(len=*),     intent(in) :: prefix
    real(kind=8),         intent(in) :: elapsed
    integer(kind=data_k), intent(in) :: siz
    logical,              intent(in) :: dorate
    ! Local
    character(len=*), parameter :: rname='TIMING>FEEDBACK'
    character(len=mess_l) :: mess
    integer(kind=data_k) :: rate
    character(len=64) :: ratestr
    !
    if (dorate) then
      if (elapsed.le.0.d0) then
        rate = 0.d0
      else
        rate = siz/elapsed
      endif
      write(ratestr,'(3A)')  '(',trim(cubetools_format_memsize(rate)),'/sec)'
    else
      ratestr = ''
    endif
    write(mess,10)  prefix,elapsed,' sec ',ratestr
    call cubeio_message(seve%r,rname,mess)
    !
10  format(A,T40,F10.2,A,A)
  end subroutine print_it

end module cubeio_timing
