export data_functions, save_path, getValues
import Pkg
Pkg.activate(".")

using DataFrames
using DelimitedFiles



# Dict of the functions used for evaluation
# QUESTION Calculate Variance for all of these?
data_type_functions = Dict(
    :served_percentage => RP.served_percentage,
    :driven_distance => RP.driven_distance,
    :requested_distance => RP.requested_distance,
    :mean_relative_delay => RP.mean_relative_delay,
   # :mean_occupancy => RP.mean_occupancy, #BUG In Reading TUples from a CSV File
)



"""
 Converts a given index to a 2D Matrix Index with the given Matrix size
"""
function getValue(index, xmin, xmax, xlen, ymin, ymax, ylen)
    xstep = (xmax-xmin)/xlen
    ystep = (ymax-ymin)/ylen


    x = (index%xlen) * xstep + xmin
    y = trunc(Int64, index/ylen) * ystep + ymin
    return x,y
end
function getLogValue(index, xmin, xmax, xlen::Int64, ymin, ymax, ylen::Int64)


    xs = exp.(LinRange(log(xmin), log(xmax), xlen))
    ys = LinRange(log(ymin), log(ymax), ylen)
    x = xs[(index)%xlen+1]
    y = ys[trunc(Int64, (index)/ylen)+1]
    return x,y
end


"""

"""
function getLogLogValue(index, xmin, xmax, xlen::Int64, ymin, ymax, ylen::Int64)


    xs = exp.(LinRange(log(xmin), log(xmax), xlen))
    ys = exp.(LinRange(log(ymin), log(ymax), ylen))
    println(length(xs));
    x = xs[(index)%xlen+1]
    y = ys[trunc(Int64, (index)/ylen)+1]
    return x,y
end

"""
 Function for Running a RidePooling simulation with the normalized Frequency x
"""
function simulate_rp(paths::Dict, N::Int64, x, y, t0::Float64, specs, request_type; served = 10*N, requested=10*N)

    #Make Model
    @time model=RP.get_model(;N_bus=N,ν=x/t0,specs...);
    @time RP.run!(model;requested=requested, served=served)
    data = Dict()
    data[:frequency] = x
    data[request_type] = y
    for (name, func) in data_type_functions
        data[name] = func(model)
    end

    # Save the calculated Data
    data = DataFrame(data)

    open(paths[:data]*"$(lpad(index, 5, "0")).csv", "w") do io
        writedlm(io, Iterators.flatten(([names(data)], eachrow(data))), ';')
    end
    #Save the model for possible later reference
    RP.savemodel(paths[:model]*"$(lpad(index, 5, "0")).model",model;route_matrix=false)
end