using OrdinaryDiffEq, DiffEqDevTools, Test

function nonauto1(u, p, t)
    x, _ = u
    return [
        t * x
        0
    ]
end

function nonauto2(u, p, t)
    _, y = u
    return [
        y,
        t * y,
    ]
end

function analytic(u0, p, t)
    x0, y0 = u0
    et = exp(t^2 / 2)
    return [
        et * (x0 + t * y0),
        et * y0,
    ]
end

u0 = [1.1, 2.2]
tspan = (0.0, 1.0)
prob1 = ODEProblem(
    ODEFunction{true}(
        (du, u, p, t) -> du .= nonauto1(u, p, t) .+
            nonauto2(u, p, t),
        analytic = analytic
    ),
    u0, tspan
)
prob2 = ODEProblem(
    ODEFunction{false}(
        (u, p, t) -> nonauto1(u, p, t) .+ nonauto2(u, p, t),
        analytic = analytic
    ),
    u0, tspan
)
prob3 = SplitODEProblem(
    SplitFunction{true}(
        (du, u, p, t) -> du .= nonauto1(u, p, t),
        (du, u, p, t) -> du .= nonauto2(u, p, t),
        analytic = analytic
    ),
    u0, tspan
)
prob4 = SplitODEProblem(
    SplitFunction{false}(
        nonauto1,
        nonauto2,
        analytic = analytic
    ),
    u0, tspan
)

testTol = 0.2

kwargs = (reltol = 1.0e-16, abstol = 1.0e-16)
for prob in [prob1, prob2, prob3, prob4]
    dts = 1 .// 2 .^ (12:-1:8)
    sim = test_convergence(dts, prob, KenCarp3(); kwargs...)
    @test sim.𝒪est[:l∞] ≈ 3 atol = testTol
    dts = 1 .// 2 .^ (9:-1:6)
    sim = test_convergence(dts, prob, CFNLIRK3(); kwargs...)
    @test sim.𝒪est[:l∞] ≈ 3 atol = testTol
    sim = test_convergence(dts, prob, KenCarp4(); kwargs...)
    @test sim.𝒪est[:l∞] ≈ 4 atol = testTol
    sim = test_convergence(dts, prob, KenCarp47(); kwargs...)
    @test sim.𝒪est[:l∞] ≈ 4 atol = testTol
    dts = 1 .// 2 .^ (7:-1:4)
    sim = test_convergence(dts, prob, KenCarp5(); kwargs...)
    @test sim.𝒪est[:l∞] ≈ 5 atol = testTol
    sim = test_convergence(dts, prob, KenCarp58(); kwargs...)
    @test sim.𝒪est[:l∞] ≈ 5 atol = testTol
end
for prob in [prob1, prob2]
    dts = 1 .// 2 .^ (7:-1:4)
    sim = test_convergence(dts, prob, ESDIRK54I8L2SA(); kwargs...)
    @test sim.𝒪est[:l∞] ≈ 5 atol = testTol
    dts = 1 .// 2 .^ (8:-1:4)
    sim = test_convergence(dts, prob, Rodas4(); kwargs...)
    @test sim.𝒪est[:l∞] ≈ 4 atol = testTol + 0.1
    dts = 1 .// 2 .^ (7:-1:3)
    sim = test_convergence(dts, prob, Rodas5(); kwargs...)
    @test sim.𝒪est[:l∞] ≈ 5 atol = testTol + 0.1
end

#=
prob = prob2
dts = 1 .//2 .^(9:-1:6)
sim = test_convergence(dts,prob,KenCarp4())
sim.𝒪est[:l∞]

using Plots
plot(sim)
=#
