### Persefone.jl - a model of agricultural landscapes and ecosystems in Europe.
###
### This tests the core input and output functions.
###

@testset "Model configuration" begin
    model = inittestmodel()
    @test @param(core.configfile) == basename(TESTPARAMETERS)
    @test @param(core.startdate) == Date(2022, 2, 1)
    @test @param(core.loglevel) == "warn"
    @test @param(nature.targetspecies) == ["Wolpertinger", "Wyvern"]
    @param(core.enddate) = Date(2022,1,3)
    @test @param(core.enddate) == Date(2022,1,3)
end

@testset "Output functions" begin
    model = inittestmodel()
    # test that the output directory is created with all files
    outdir = @param(core.outdir)
    @test_logs((:debug, "Setting up output directory results_testsuite."),
               min_level=Logging.Debug, match_mode=:any,
               Ps.createdatadir(outdir, @param(core.overwrite)))
    @test isdir(outdir)
    Ps.saveinputfiles(model)
    @test isfile(joinpath(outdir, Ps.RECORDDIR, @param(world.landcovermap)))
    @test isfile(joinpath(outdir, Ps.RECORDDIR, @param(world.farmfieldsmap)))
    @test isfile(joinpath(outdir, Ps.RECORDDIR, @param(world.weatherfile)))
    @test isfile(joinpath(outdir, Ps.RECORDDIR, @param(core.configfile)))
    # test log output to screen/file/both
    #XXX cannot test logger output due to https://github.com/JuliaLang/julia/issues/48456
    logger1 = Ps.modellogger(@param(core.loglevel), outdir, "screen")
    @test !isfile(joinpath(outdir, Ps.LOGFILE))
    logger2 = Ps.modellogger(@param(core.loglevel), outdir, "file")
    @test isfile(joinpath(outdir, Ps.LOGFILE))
    rm(joinpath(outdir, Ps.LOGFILE))
    logger3 = Ps.modellogger(@param(core.loglevel), outdir, "both")
    @test isfile(joinpath(outdir, Ps.LOGFILE))
    # check whether the overwrite warning/protection works
    @test_logs((:warn, "Overwriting existing output directory $(outdir)."),
               match_mode=:any,
               Ps.createdatadir(outdir, @param(core.overwrite)))
    @test_throws ErrorException Ps.createdatadir(outdir, false)
    # test that creating a DataOutput works, and outputs data with the required frequency
    testoutput(model) = [[string(model.date)]]
    Ps.newdataoutput!(model, "never", ["Date"], testoutput, "never")
    Ps.newdataoutput!(model, "daily", ["Date"], testoutput, "daily")
    Ps.newdataoutput!(model, "monthly", ["Date"], testoutput, "monthly")
    Ps.newdataoutput!(model, "yearly", ["Date"], testoutput, "yearly")
    Ps.newdataoutput!(model, "end", ["Date"], testoutput, "end")
    @param(core.enddate) = Date(2023,2,1)
    @test_logs((:info, "Simulated 366 days."),
               match_mode=:any,
               simulate!(Ps.withtestlogger(model)))
    @param(core.enddate) = Date(2022,3,31) # change back to original to prevent errors
    @test !isfile(joinpath(outdir, "never.csv"))
    @test isfile(joinpath(outdir, "daily.csv"))
    @test countlines(joinpath(outdir, "daily.csv")) == 367
    @test size(model.datatables["daily"]) == (366, 1)
    @test isfile(joinpath(outdir, "monthly.csv"))
    @test countlines(joinpath(outdir, "monthly.csv")) == 14
    @test size(model.datatables["monthly"]) == (13, 1)
    @test isfile(joinpath(outdir, "yearly.csv"))
    @test countlines(joinpath(outdir, "yearly.csv")) == 3
    @test size(model.datatables["yearly"]) == (2, 1)
    @test isfile(joinpath(outdir, "end.csv"))
    @test countlines(joinpath(outdir, "end.csv")) == 2
    @test size(model.datatables["end"]) == (1, 1)
    rm(outdir, force=true, recursive=true)
end

@testset "Model object serialization" begin
    model = inittestmodel()
    Ps.createdatadir(@param(core.outdir), true)
    originalenddate = @param(core.enddate)
    @param(core.enddate) = Date(year(model.date), 2, 5)
    @test_logs((:debug, "Saved model object to results_testsuite/test.dat."),
               min_level=Logging.Debug, match_mode=:any,
               savemodelobject(model, "test"))
    @test isfile(joinpath(@param(core.outdir), "test.dat"))
    model2 = loadmodelobject(joinpath(@param(core.outdir), "test.dat"))
    @test model.date == model2.date
    @test model.settings == model2.settings
    @test Ps.nagents(model) == Ps.nagents(model2)
    simulate!(Ps.withtestlogger(model))
    simulate!(Ps.withtestlogger(model2))
    @test model.date == model2.date
    @test Ps.nagents(model) == Ps.nagents(model2)
    rm(@param(core.outdir), force=true, recursive=true)
    @param(core.enddate) = originalenddate
end

@testset "Output visualisation" begin
    model = initialise(TESTPARAMETERS)
    stepsimulation!(model)
    @test_logs((:debug, "Visualising output."),
               min_level=Logging.Debug, match_mode=:any,
               visualiseoutput(model))
    @test isfile(joinpath(@param(core.outdir), "individuals.pdf"))
    @test isfile(joinpath(@param(core.outdir), "populations.pdf"))
    rm(@param(core.outdir), force=true, recursive=true)
end