package ballistics.orbitalPoints

import ballistics.Ballistics
import ballistics.types.*
import ballistics.utils.math.Vector3D
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
import java.time.LocalDateTime
import java.time.ZoneOffset
import kotlin.math.PI

internal class OrbitalPointsIntegratorTest {
    @Test
    fun testMDBARS() {
        val r = Ballistics()

        r.earthType = EarthType.PZ90d02
        r.modDVType = ModDVType.BARS
        r.integrationType = IntegrationType.ADAMS7

        val mnu = mutableListOf<InitialConditions>()
        mnu.add(
            InitialConditions(
                OrbitalPoint(
                    LocalDateTime.of(2021, 12, 3, 0, 5, 45, 0).toEpochSecond(ZoneOffset.UTC).toDouble(),
                    1,
                    Vector3D(
                        -5357933.7872,
                        4328646.1787,
                        0.0,
                    ),
                    Vector3D(
                        941.8995373,
                        1150.6919822,
                        7544.9920840,
                    ),
                ),
                0.0061,
                125.0,
            ),
        )
        val rez = r.calculateOrbPoints(mnu.toTypedArray(), mnu.first().point.t, mnu.first().point.t + 86400.0 * 3)

        for (p in r.revolutions) {
            println(
                "${p.vuz.vit}  ${LocalDateTime.ofEpochSecond(p.vuz.t.toLong(),0, ZoneOffset.UTC)}  " +
                    "${p.lVuz * 180.0 / PI} " +
                    " ${p.hVuz}  " +
                    "${p.vuz.r.x} " +
                    " ${p.vuz.r.y}  " +
                    "${p.vuz.r.z} " +
                    " ${p.vuz.v.x}  " +
                    "${p.vuz.v.y} " +
                    " ${p.vuz.v.z}",
            )
        }

        val p = r.points.last()
        println(
            "${p.vit}  ${LocalDateTime.ofEpochSecond(
                p.t.toLong(),
                0,
                ZoneOffset.UTC,
            )}  ${p.r.x}  ${p.r.y}  ${p.r.z}  ${p.v.x}  ${p.v.y}  ${p.v.z}",
        )

        val rc = Vector3D(r.points.last().r.x, r.points.last().r.y, r.points.last().r.z)
        val vc = Vector3D(r.points.last().v.x, r.points.last().v.y, r.points.last().v.z)

        val rex = Vector3D(4723743.916, -4261060.842, -2647685.695)
        val vex = Vector3D(-3168.702, 797.721, -6953.781)

        val dr = (rc - rex).module()
        val dv = (vex - vc).module()

        println(dr)
        println(dv)


        assertEquals(
            BallisticsError.OK,
            rez,
        )
        assertTrue(
            dr < 0.01,
            "Ошибка прогноза по радиус-вектору",
        )
        assertTrue(dv < 0.01, "ошибка прогноза по вектору скорости")
    }


//    fun initOrekitData() {
//        val dataDir = File("src/main/resources/orekit-data-main") // or absolute path
//        if (!dataDir.exists()) {
//            throw IllegalStateException("Orekit data directory not found at ${dataDir.absolutePath}")
//        }
//        val crawler = DirectoryCrawler(dataDir)
//        DataProvidersManager.getInstance().addProvider(crawler)
//    }

//    @Test
//    fun orekitTest(){
//
//        initOrekitData()
//
//        val l1 = "1 00666U 18111A   25349.99139990  .00002772  00000+0  11883-3 0  9999"
//        val l2 = "2 43876  97.3687 252.5788 0001999  83.2822 276.8643 15.23576679386900"
//
//        val tle = TLE(l1, l2)
//        val sat = Satellite(org.nstart.dep265.tletools.zeptomoby.core.TLE("",l1, l2))
//
//        assertTrue { sat.orbit.satId.toInt() == tle.satelliteNumber }
//    }
}
