using Sundials, Test
import ODEProblemLibrary: prob_ode_linear, prob_ode_2Dlinear

prob = prob_ode_2Dlinear
integrator = init(prob, CVODE_BDF())
step!(integrator)
integrator(integrator.t, Val{1})

for i in integrator
    @info i.t
end

integrator.t == 1.0
step!(integrator)
integrator.t > 1.0

reinit!(integrator)
solve!(integrator)
u1 = copy(integrator.u)
reinit!(integrator)
solve!(integrator)
u2 = copy(integrator.u)
@test u1 != vec(prob.u0)
@test u1 == u2

f_terminate(u, p, t) = [2 * u[1]]
u_positive(u, t, integrator) = u[1] > 0
terminate_if_u_pos = DiscreteCallback(u_positive, terminate!)

prob = ODEProblem(f_terminate, [1.0], (0.0, 1.0)) # positive initial condition > positive u > Terminated
integrator = init(prob, CVODE_BDF(); callback = terminate_if_u_pos)
sol1 = solve!(integrator)
@test sol1.retcode == ReturnCode.Terminated

reinit!(integrator, [-1.0]) # negative initial condition > negative u > Success!
sol2 = solve!(integrator)
@test sol2.retcode == ReturnCode.Success

prob = ODEProblem(f_terminate, [-1.0], (0.0, 1.0)) # negative initial condition > negative u > Success!
integrator = init(prob, CVODE_BDF(); callback = terminate_if_u_pos)
sol3 = solve!(integrator)
@test sol3.retcode == ReturnCode.Success
