# Support for ParaView JSON .series files for time series.
# Seem to work correctly with VTKHDF files.
#
# https://gitlab.kitware.com/paraview/paraview/-/blob/v5.5.0/Documentation/release/ParaView-5.5.0.md#json-based-new-meta-file-format-for-series-added

using FileIO: FileIO, save

export TimeSeriesFile, save

"""
    TimeSeriesFile() -> TimeSeriesFile

Initialise a time series file compatible with ParaView.

A [ParaView time series file](https://gitlab.kitware.com/paraview/paraview/-/blob/v5.5.0/Documentation/release/ParaView-5.5.0.md#json-based-new-meta-file-format-for-series-added)
is a JSON which points to a series of VTK files representing a time series.
To each VTK file one can associate a (simulation) time.

One can use this to describe a series of VTKHDF files generated by [`write_vtkhdf`](@ref).
Note that, in this case, the extension of the time series file must be `.vtkhdf.series`.

# Typical usage

```julia
# Initialise TimeSeriesFile before starting a simulation
tsf = TimeSeriesFile()

# Write a VTKHDF file associated to a single time
timestep = 4200
time = 24.0
filename = "rings_\$(timestep).vtkhdf"
write_vtkhdf(filename, filaments, etc...)  # write VTKHDF file
tsf[time] = filename                       # add VTKHDF file to time series file

# Save the file at the end of the simulation (or at an intermediate time, that's OK too)
save("rings.vtkhdf.series", tsf)  # note: the extension must be .vtkhdf.series to make ParaView happy
```
"""
struct TimeSeriesFile
    files :: Vector{String}   # list of files (*.vtkhdf)
    times :: Vector{Float64}  # times associated to each file
end

function TimeSeriesFile()
    TimeSeriesFile(String[], Float64[])
end

"""
    Base.empty!(tsf::TimeSeriesFile)

Reset [`TimeSeriesFile`](@ref), removing all entries.
"""
function Base.empty!(tsf::TimeSeriesFile)
    empty!(tsf.files)
    empty!(tsf.times)
    tsf
end

"""
    Base.setindex!(tsf::TimeSeriesFile, filename::AbstractString, time::Real)

Add file to time series file.

# Typical usage

```julia
timestep = 4200
time = 24.0
filename = "rings_\$(timestep).vtkhdf"
tsf[time] = filename
```
"""
function Base.setindex!(tsf::TimeSeriesFile, filename::AbstractString, time::Real)
    push!(tsf.files, filename)
    push!(tsf.times, time)
    nothing
end

"""
    save(filename::AbstractString, tsf::TimeSeriesFile)
    save(io::IO, tsf::TimeSeriesFile)

Write [`TimeSeriesFile`](@ref) to a file.

The filename must have extension `.VTKFORMAT.series`.
In particular, if writing VTKHDF files, the format must be `.vtkhdf.series`.
"""
function FileIO.save(filename::AbstractString, tsf::TimeSeriesFile)
    open(filename, "w") do io
        save(io, tsf)
    end
end

# Manually create JSON file
function FileIO.save(io::IO, tsf::TimeSeriesFile)
    (; files, times,) = tsf
    @assert eachindex(files) == eachindex(times)
    print(
        io,
        """
        {
          "file-series-version" : "1.0",
          "files" : [
        """
    )
    inds = eachindex(files, times)
    for i âˆˆ inds
        print(io, "    { \"name\" : \"", files[i], "\", \"time\" : ", times[i], " }")
        if i !== last(inds)
            print(io, ',')
        end
        print(io, '\n')
    end
    println(io, "  ]")
    println(io, '}')
    nothing
end
