using LatticeGPU
using TOML
using TimerOutputs
using ArgParse
using CUDA


function therm_or_readlist()

    println(log_file,"\nStarting simulation\n")
    if parsed_args["c"] == nothing
        println(log_file,"Thermalizing...")
        flush(log_file)
        @timeit "Thermalization" for _ in 1:params["HMC"]["nth"]
            HMC!(U,intsch,lp,gp,ymws)
        end
    else
        println(log_file,"Loading gauge configurations from "*string(parsed_args["c"]))
        read_config_list()
        flush(log_file)
    end
    f = open("RUN_ON_"*params["Run"]["name"],"w+")
    close(f)

    return nothing
end

function check_run_status()

    if parsed_args["c"] == nothing
        global RUN_ON = isfile("RUN_ON_"*params["Run"]["name"])
    else
        global RUN_ON = (isfile("RUN_ON_"*params["Run"]["name"]) && CONFIG_LIST[MCid+1] != "./cnfg/")
    end

    if MCid == params["HMC"]["mclength"]
        global RUN_ON = false
    end

    return nothing
end

function Gauge_update()
    if parsed_args["c"] == nothing
        Gauge_update_hmc()
        global RUN_ON = isfile("RUN_ON_"*params["Run"]["name"])
    else
        load_gauge_field()
        global RUN_ON = (isfile("RUN_ON_"*params["Run"]["name"]) && CONFIG_LIST[MCid+1] != "./cnfg/")
    end

    return nothing
end

function Gauge_update_hmc()

    println(log_file,"Performing "*string(params["HMC"]["dmeas"])*" HMC steps...")
    flush(log_file)

    global dH = 0.0
    global acc = true

    for _ in 1:params["HMC"]["dmeas"]
        dH,acc = HMC!(U,intsch,lp,gp,ymws)
        acc ? (global Nmc_acc += 1) : println(log_file,"Rejected HCM step")
    end
    global MCid = MCid + 1
    println(log_file,"Updated to Gauge configuration n"*string(MCid))
    println(log_file,"dH   = ",dH)
    println(log_file,"acc  = ",Nmc_acc/(params["HMC"]["dmeas"] * MCid))
    println(log_file,"Plaq = ", plaquette(U, lp, gp, ymws))
    println(log_file,"Qtop = ", Qtop(U, gp, lp, ymws))

    Csw!(dws,U,gp,lp)
    U_CPU .= Array(U)

    flush(log_file)
    return nothing
end


function read_config_list()
    global CONFIG_LIST = Vector{String}(undef,0)
    f = open(parsed_args["c"],"r")
    while true
        push!(CONFIG_LIST,"./cnfg/"*readline(f))
        CONFIG_LIST[end] == "./cnfg/" ? break : nothing
    end
    println(log_file,"Read ", length(CONFIG_LIST)-1, " config names for analisis")
    return nothing
end


"""
    function load_gauge_field()

Loads the gauge field and computes the Csw term
"""
function load_gauge_field()

    global MCid = MCid + 1

    if !parsed_args["cern"]
        println(log_file,"\nReading gauge field with LGPU native convention: ", CONFIG_LIST[MCid], "...")
        global U,_ = read_cnfg(CONFIG_LIST[MCid])
    else
        println(log_file,"\nReading gauge field with CERN convention: ", CONFIG_LIST[MCid], "...")
        global U = import_cern64(CONFIG_LIST[MCid],0,lp,log=false)
    end

    println(log_file,"Updated to Gauge configuration n"*string(MCid))
    f = open(CONFIG_LIST[MCid],"r")
    println(log_file,"MD5 checksum of gauge config: ",bytes2hex(md5(f)),"\n")
    close(f)
    println(log_file,"Plaq = ", plaquette(U, lp, gp, ymws))
    println(log_file,"Qtop = ", Qtop(U, gp, lp, ymws))

    Csw!(dws,U,gp,lp)
    U_CPU .= Array(U)

    flush(log_file)
    return nothing
end
