# using LatticeGPU
using ADerrors
using BDIO


function read_ff(name::String)

    file = BDIO_open(name,"r","FerFlow correlators")

    while BDIO_get_uinfo(file) != 1
        BDIO_seek!(file)
    end
    dims=Vector{Int32}(undef,1)
    iL=Vector{Int32}(undef,4)
    dpars=Vector{Float64}(undef,2) # m0,csw
    th=Vector{ComplexF64}(undef,4)
    nflow=Vector{Int32}(undef,1)
    N_noise=Vector{Int32}(undef,1)

    BDIO_read(file, dims)
    BDIO_read(file, iL)
    BDIO_read(file, dpars)
    BDIO_read(file, th)
    BDIO_read(file, nflow)
    flow_times=Vector{Float64}(undef,nflow[1])
    nflow[1] > 0 ? BDIO_read(file, flow_times) : nothing
    BDIO_read(file, N_noise)

    N_noise = N_noise[1]
    nflow = nflow[1]
    TvecR = Vector{Float64}(undef,iL[4]);
    TvecC = Vector{ComplexF64}(undef,iL[4]);
    CN = Vector{ComplexF64}(undef,1);
    RN = Vector{Float64}(undef,1);
    ET = Vector{ComplexF64}(undef,1+nflow);

    pp_corr = Array{Float64}(undef,1,iL[4],N_noise);
    ap_corr = Array{ComplexF64}(undef,1,iL[4],N_noise);
    pp_corr_t = Array{Float64}(undef,1,iL[4],N_noise,nflow);
    ap_corr_t = Array{ComplexF64}(undef,1,iL[4],N_noise,nflow);
    pp_corr_tfl = Array{Float64}(undef,1,iL[4],N_noise,nflow);
    ap_corr_tfl = Array{ComplexF64}(undef,1,iL[4],N_noise,nflow);
    Sigma = Array{ComplexF64}(undef,1,iL[4],N_noise,nflow);
    Sigma_cfl = Array{ComplexF64}(undef,1,iL[4],N_noise,nflow);
    Sigma2 = Array{ComplexF64}(undef,1,iL[4],N_noise,nflow);
    Sigma2_cfl = Array{ComplexF64}(undef,1,iL[4],N_noise,nflow);
    ChiDchi = Array{ComplexF64}(undef,1,iL[4],N_noise,nflow);
    ChiDchi_cfl = Array{ComplexF64}(undef,1,iL[4],N_noise,nflow);
    Phat_t = Array{Float64}(undef,1,N_noise,nflow);
    Eoft = Array{Complex{Float64}}(undef,1,1+nflow,iL[4]);

    pp_corr_mc = Array{Float64}(undef,0,iL[4],N_noise);
    ap_corr_mc = Array{ComplexF64}(undef,0,iL[4],N_noise);
    pp_corr_t_mc = Array{Float64}(undef,0,iL[4],N_noise,nflow);
    ap_corr_t_mc = Array{ComplexF64}(undef,0,iL[4],N_noise,nflow);
    pp_corr_tfl_mc = Array{Float64}(undef,0,iL[4],N_noise,nflow);
    ap_corr_tfl_mc = Array{ComplexF64}(undef,0,iL[4],N_noise,nflow);
    Sigma_mc = Array{ComplexF64}(undef,0,iL[4],N_noise,nflow);
    Sigma_cfl_mc = Array{ComplexF64}(undef,0,iL[4],N_noise,nflow);
    Sigma2_mc = Array{ComplexF64}(undef,0,iL[4],N_noise,nflow);
    Sigma2_cfl_mc = Array{ComplexF64}(undef,0,iL[4],N_noise,nflow);
    ChiDchi_mc = Array{ComplexF64}(undef,0,iL[4],N_noise,nflow);
    ChiDchi_cfl_mc = Array{ComplexF64}(undef,0,iL[4],N_noise,nflow);
    Phat_t_mc = Array{Float64}(undef,0,N_noise,nflow);
    Eoft_mc = Array{Complex{Float64}}(undef,0,1+nflow,iL[4]);

    while BDIO_get_uinfo(file) != 8
        BDIO_seek!(file)
    end

    while BDIO_get_uinfo(file) == 8

        for noi in 1:N_noise
            BDIO_read(file,TvecR)
            pp_corr[1,:,noi] .= TvecR

            BDIO_read(file,TvecC)
            ap_corr[1,:,noi] .= TvecC

            for fl in 1:nflow
                BDIO_read(file,TvecR)
                pp_corr_t[1,:,noi,fl].= TvecR

                BDIO_read(file,TvecC)
                ap_corr_t[1,:,noi,fl].= TvecC

                BDIO_read(file,TvecR)
                pp_corr_tfl[1,:,noi,fl].= TvecR

                BDIO_read(file,TvecC)
                ap_corr_tfl[1,:,noi,fl].= TvecC

                BDIO_read(file,TvecC)
                Sigma[1,:,noi,fl] .= TvecC
                BDIO_read(file,TvecC)
                Sigma_cfl[1,:,noi,fl] .= TvecC

                BDIO_read(file,TvecC)
                Sigma2[1,:,noi,fl] .= TvecC
                BDIO_read(file,TvecC)
                Sigma2_cfl[1,:,noi,fl] .= TvecC

                BDIO_read(file,TvecC)
                ChiDchi[1,:,noi,fl] .= TvecC
                BDIO_read(file,TvecC)
                ChiDchi_cfl[1,:,noi,fl] .= TvecC

                BDIO_read(file,RN)
                Phat_t[1,noi,fl]= RN[1]
            end
        end
        for time in 1:iL[4]
            BDIO_read(file,ET)
            Eoft[1,:,time] .= ET
        end
        Eoft_mc=[Eoft_mc;Eoft]

        pp_corr_mc=[pp_corr_mc;pp_corr]
        ap_corr_mc=[ap_corr_mc;ap_corr]
        pp_corr_t_mc=[pp_corr_t_mc;pp_corr_t]
        ap_corr_t_mc=[ap_corr_t_mc;ap_corr_t]
        pp_corr_tfl_mc=[pp_corr_tfl_mc;pp_corr_tfl]
        ap_corr_tfl_mc=[ap_corr_tfl_mc;ap_corr_tfl]
        Sigma_mc=[Sigma_mc;Sigma]
        Sigma_cfl_mc=[Sigma_cfl_mc;Sigma_cfl]
        Sigma2_mc=[Sigma2_mc;Sigma2]
        Sigma2_cfl_mc=[Sigma2_cfl_mc;Sigma2_cfl]
        ChiDchi_mc=[ChiDchi_mc;ChiDchi]
        ChiDchi_cfl_mc=[ChiDchi_cfl_mc;ChiDchi_cfl]
        Phat_t_mc=[Phat_t_mc;Phat_t]

        BDIO_seek!(file)
        BDIO_seek!(file)
    end

    BDIO_close!(file)

    return Eoft_mc,pp_corr_mc,ap_corr_mc,pp_corr_t_mc,ap_corr_t_mc,pp_corr_tfl_mc,ap_corr_tfl_mc,Sigma_mc,Sigma_cfl_mc,Sigma2_mc,Sigma2_cfl_mc,ChiDchi_mc,ChiDchi_cfl_mc,Phat_t_mc
end


"""
function uwff(file::String)

Loads in the variables 'Eoft', 'pp_corr', 'ap_corr', 'pp_corr_t','ap_corr_t', 'Sigma' and 'Sigma_cfl' the corresponding
'uwreal' quantities. The indices are, when corresponding, eucliden time and flow times
"""
function uwff(file::String)
    Eoft_mc,pp_corr_mc,ap_corr_mc,pp_corr_t_mc,ap_corr_t_mc,pp_corr_tfl_mc,ap_corr_tfl_mc,Sigma_mc,Sigma_cfl_mc,Sigma2_mc,Sigma2_cfl_mc,ChiDchi_mc,ChiDchi_cfl_mc,Phat_t_mc = read_ff(file)
    runame = String(split(split(file,"/")[end],".")[1])

    T = size(pp_corr_mc)[2]
    Ns = size(pp_corr_mc)[3]
    Nfl = size(pp_corr_t_mc)[4]

    global Eoft = [uwreal(real.(Eoft_mc[:,i,j]),runame) for j in 1:T, i in 1:Nfl+1]

    global pp_corr = [uwreal(sum(pp_corr_mc,dims = 3)[:,i,1]./Ns,runame) for i in 1:T]
    global ap_corr = [uwreal(real.(sum(ap_corr_mc,dims = 3)[:,i,1]./Ns),runame) for i in 1:T]

    global pp_corr_t = [uwreal(sum(pp_corr_t_mc,dims = 3)[:,i,1,k]./Ns,runame) for i in 1:T, k in 1:Nfl]
    global ap_corr_t = [uwreal(real.(sum(ap_corr_t_mc,dims = 3)[:,i,1,k]./Ns),runame) for i in 1:T,k in 1:Nfl]

    global pp_corr_tfl = [uwreal(sum(pp_corr_tfl_mc,dims = 3)[:,i,1,k]./Ns,runame) for i in 1:T, k in 1:Nfl]
    global ap_corr_tfl = [uwreal(real.(sum(ap_corr_tfl_mc,dims = 3)[:,i,1,k]./Ns),runame) for i in 1:T,k in 1:Nfl]

    global Sigma = [uwreal(real.(sum(Sigma_mc,dims = 3)[:,i,1,k]./Ns),runame) for i in 1:T, k in 1:Nfl]
    global Sigma_cfl = [uwreal(real.(sum(Sigma_cfl_mc,dims = 3)[:,i,1,k]./Ns),runame) for i in 1:T, k in 1:Nfl]

    global Sigma2 = [uwreal(real.(sum(Sigma2_mc,dims = 3)[:,i,1,k]./Ns),runame) for i in 1:T, k in 1:Nfl]
    global Sigma2_cfl = [uwreal(real.(sum(Sigma2_cfl_mc,dims = 3)[:,i,1,k]./Ns),runame) for i in 1:T, k in 1:Nfl]

    global ChiDchi = [uwreal(real.(sum(ChiDchi_mc,dims = 3)[:,i,1,k]./Ns),runame) for i in 1:T, k in 1:Nfl]
    global ChiDchi_cfl = [uwreal(real.(sum(ChiDchi_cfl_mc,dims = 3)[:,i,1,k]./Ns),runame) for i in 1:T, k in 1:Nfl]

    global Phat_t = [uwreal(sum(Phat_t_mc,dims = 2)[:,1,i]./Ns,runame) for i in 1:Nfl]
    return nothing
end
