package icurves.diagram

import com.fasterxml.jackson.core.Version
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.module.kotlin.readValue
import com.fasterxml.jackson.module.kotlin.registerKotlinModule
import icurves.description.D
import icurves.description.Description
import icurves.util.Log
import icurves.util.PathDeserializer
import icurves.util.PathSerializer
import icurves.util.Point2DDeserializer
import javafx.application.Application
import javafx.geometry.Point2D
import javafx.scene.shape.Path
import javafx.stage.Stage
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.MatcherAssert.assertThat
import org.junit.jupiter.api.BeforeAll
import java.io.File
import java.util.concurrent.CountDownLatch

/**
 *
 *
 * @author Almas Baimagambetov (almaslvl@gmail.com)
 */
class DiagramCreatorTest {

    // TODO: load this from Examples
    private val testData = listOf(
            "a b ab",
            "a b c abc ab ac bc",
            "a b c d ab ac ad bc bd cd abc abd acd bcd abcd",
            "a b c d e ab ac ad ae bc bd be cd ce de abc abd abe acd ace ade bcd bce bde cde abcd abce abde acde bcde abcde"
    )

    // mock javafx app so we can init graphics toolkit
    companion object {

        private val objectMapper = ObjectMapper().registerKotlinModule()

        init {
            val diagramModule = SimpleModule("PointModule", Version(1, 0, 0, "", "", ""))
            diagramModule.addDeserializer(Point2D::class.java, Point2DDeserializer())
            diagramModule.addSerializer(Path::class.java, PathSerializer())
            diagramModule.addDeserializer(Path::class.java, PathDeserializer())

            objectMapper.registerModule(diagramModule)
        }

        private val count = CountDownLatch(1)

        @BeforeAll
        @JvmStatic fun before() {
            Thread(Runnable {
                Application.launch(MockApp::class.java)
            }).start()

            count.await()
        }
    }

    class MockApp : Application() {
        override fun start(stage: Stage?) {
            count.countDown()
        }
    }

    //@Test
    fun `Generate`() {
        testData.forEach {
            val d1 = d(D(it))

            //val fileName = "icurves/diagram/diagrams/" + "${d1.originalDescription.getInformalDescription()}.json"

            val fileName = javaClass.getResource("diagrams/${d1.originalDescription.getInformalDescription()}.json")

            val d2 = objectMapper.readValue<EulerDiagram>(File(fileName.toURI()))

            Log.d("actual", d1)
            Log.d("loaded", d2)

            assertThat(d1, `is`(d2))
        }
    }

    //@Test
    fun `Write test data`() {
        testData.forEach {
            val d = d(D(it))
            objectMapper.writeValue(File("${d.originalDescription.getInformalDescription()}.json"), d)
        }
    }

    private fun d(D: Description) = DiagramCreator().createDiagram(D)
}