module restart 
use precision
implicit none

public restart_io

save

contains
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine restart_native(iop)
    use global_parameters, only: mype, istep, mstepall, gtcout, mi, nparami, gtcout, irest,mfki,nparamfki,me,nparame
    use read_in_parameters, only: mstep, ifullk
    use particle_array
    use grids_fields
    use fluid
    character(*),intent(in) :: iop
    character(len=80) :: restart_fname
    character(len=18) :: cdum
    integer :: ierror

    if (mype < 10) then

        write(cdum,'("DATA_RESTART.0000",i1)')mype

    elseif (mype < 100) then

        write(cdum,'("DATA_RESTART.000",i2)')mype

    elseif (mype < 1000) then

        write(cdum,'("DATA_RESTART.00",i3)')mype

    elseif (mype < 10000) then

        write(cdum,'("DATA_RESTART.0",i4)')mype

    else 

        write(cdum,'("DATA_RESTART.",i5)')mype

    endif
!========================================================
    if (mod(irest,2)==0) then
        restart_fname="restart_dir1/"//trim(cdum)
    else
        restart_fname="restart_dir2/"//trim(cdum)
    endif

    call MPI_BARRIER(MPI_COMM_WORLD, ierror)

!========================================================
    if(iop=="write")then

        open(222,file=trim(restart_fname),status='replace',form='unformatted')

            if(ifullk==0)then
#ifndef GPU_UM
                !$acc update host(zion(:,1:mi),zion0(:,1:mi))
#endif
                write(222)mi
                write(222)pmarki, markeri, marknumi, nonunii
                write(222)zion(1:nparami,1:mi),zion0(1:nparami,1:mi)
                write(222)pfluxi, rdtemi
            else
#ifndef GPU_UM
                !$acc update host(zfki(:,1:mfki),zfki0(:,1:mfki))
#endif
                write(222)mfki
                write(222)pmarkfki, markerfki, marknumfki, nonunifki
                write(222)zfki(1:nparamfki,1:mfki),zfki0(1:nparamfki,1:mfki)
                write(222)pfluxfki, rdtemfki
            endif
            write(222)me
            write(222)pmarke, markere,marknume,nonunie
#ifndef GPU_UM
                !$acc update host(zelectron(:,1:me),zelectron0(:,1:me))
#endif
            write(222)zelectron(1:nparame,1:me),zelectron0(1:nparame,1:me)
            write(222)pfluxe, rdteme

        close(222)
        if(mype==0)write(gtcout,*)"write to ",trim(restart_fname)
        call restart_hist

    elseif(iop=="read")then

        if(mype==0)write(gtcout,*)"read in ",trim(restart_fname)
        open(333,file=trim(restart_fname),status='old',form='unformatted')
            if(ifullk==0)then
                read(333)mi
                read(333)pmarki, markeri, marknumi, nonunii
                read(333)zion(1:nparami,1:mi),zion0(1:nparami,1:mi)
                read(333)pfluxi, rdtemi
#ifndef GPU_UM
                !$acc update device(zion(:,1:mi),zion0(:,1:mi))
#endif
            else
                read(333)mfki
                read(333)pmarkfki, markerfki, marknumfki, nonunifki
                read(333)zfki(1:nparamfki,1:mfki),zfki0(1:nparamfki,1:mfki)
                read(333)pfluxfki,rdtemfki
#ifndef GPU_UM
                !$acc update host(zfki(:,1:mfki),zion0(:,1:mfki))
#endif
            endif
        read(333)me
        read(333)pmarke, markere, marknume, nonunie
        read(333)zelectron(1:nparame,1:me),zelectron0(1:nparame,1:me)
        read(333)pfluxe,rdteme
#ifndef GPU_UM
                !$acc update host(zion(:,1:me),zelectron0(:,1:me))
#endif
     
        close(333)
        irest = irest + 1   ! Rolling restart index accumulation
        if(mype==0)write(gtcout,*)restart_fname,'read over'

    endif


end subroutine restart_native
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine restart_io(iop)
    use global_parameters, only: mype, gtcout
    character(*), intent(in) :: iop


    if(iop/="read" .and. iop/="write")then
        if(mype==0)write(gtcout,*)'*** subroutine restart_io (iop <> "read" or "write")',iop
        call GTC_ABORT
        return
    endif
    call restart_native(iop)
end subroutine restart_io
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine restart_hist
    use global_parameters, only: mype, istep, mstepall, mtoroidal, gtcout, &
                                 irest, FileExit, data1d_on
    use read_in_parameters, only: mstep, ndiag, diag_region, iflux_core, iflux_sol
    use data_output, only: frcdiag, frcdata1d, partdiag
    use grids_setup, only: mpara_sol, mpara_core

    integer, parameter :: nfield2=11
    integer :: mstepfinal, ndstep, ndata, i, j, idum
    real(lk) :: tdum, time_step_dum
    character(len=80) :: restart_fname
    character(len=25) :: txt25
    character(len=99) :: tmpline
    integer :: countline1,num_Var,ndim(6),tmpid,tmpSize
    
    if(mype==0 .and. istep <= mstep)then
        if(mod(irest,2)==0)then
            restart_fname="restart_dir1/"
        else
            restart_fname="restart_dir2/"
        endif
!=========================================================
! history.out
        open(333, file=trim(restart_fname)//'frc_history_restart.out',status='replace')
        rewind(frcdiag)
        read(frcdiag,101)mstepfinal
        ndstep=mstepfinal-mstep/ndiag+istep/ndiag
        write(333,101)ndstep
        read(frcdiag,102)time_step_dum
        write(333,102)time_step_dum
        ndata=nfield2
        do i=1,ndata*ndstep
            read(frcdiag,102)tdum
            write(333,102)tdum
        enddo
        close(333)
        write(gtcout,*)'write to ',trim(restart_fname)//'frc_history_restart.out'
!==========================================================
        if(data1d_on==1)then
! data1d.out
            ndstep=mstepfinal-mstep/ndiag+istep/ndiag
            countline1=0
            ndata=0
            open(444,file=trim(restart_fname)//'frc_data1d_restart.out',status='replace')
            rewind(frcdata1d)   !read from the beginning

            read(frcdata1d,'(A,i6)')txt25,num_var
            write(444,'(A,i6)')txt25,num_var
            do i=1,num_var
                read(frcdata1d,'(A)')tmpline
                txt25=tmpline(1:25)
                read(tmpline(26:31),'(i6)') ndim(1)
                tmpSize = 1
                do j=1,ndim(1)
                    tmpid = 26+j*6
                    read(tmpline(tmpid:tmpid+6),*) ndim(j+1)
                    tmpSize=tmpSize*ndim(j+1)
                enddo
                countline1=countline1+1
                write(444,'(A)')trim(tmpline)
            enddo

            read(frcdata1d,'(A,i6)')txt25,num_var
            write(444,'(A,i6)')txt25,num_var
            do i=1,num_var
                read(frcdata1d,'(A)')tmpline
                txt25=tmpline(1:25)
                read(tmpline(26:31),'(i6)') ndim(1)
                tmpSize = 1
                do j=1,ndim(1)
                    tmpid = 26+j*6
                    read(tmpline(tmpid:tmpid+6),*) ndim(j+1)
                    tmpSize=tmpSize*ndim(j+1)
                enddo
                ndata=ndata+tmpSize
                write(444,'(A)')trim(tmpline)
            enddo

            do i=2,countline1
                read(frcdata1d,'(A)')tmpline
                write(444,'(A)')trim(tmpline)
            enddo
            read(frcdata1d,101)tmpSize
            write(444,'(i6)')ndstep

            do i=1,ndata*ndstep
                read(frcdata1d,'(A)')tmpline
                write(444,'(A)')trim(tmpline)
            enddo

            close(444)
            write(gtcout,*)'write to ',trim(restart_fname)//'frc_data1d_restart.out'
        endif
!=========================================================
! save current location of restart files
        open(555,file="FileExit.out",status="replace")
        write(555,"(A9,i1)")"FileExit=",FileExit
        write(555,"(A9,i5)")"irest   =",irest+1
        if(mod(irest,2)==0)then
           write(555,"(A12)")"restart_dir1"
        else
           write(555,"(A12)")"restart_dir2"
        endif
        close(555)


        if(istep==mstep)then
            close(frcdiag)
            if(data1d_on==1)close(frcdata1d)
            close(partdiag)
        endif
    endif

    irest = irest + 1 !XY rolling restart
101 format(i6)
102 format(e13.6)
end subroutine restart_hist

end module restart
