package space.nstart.pcp.pcp_mission_planing_service.configuration

import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonDeserializer
import com.fasterxml.jackson.databind.JsonSerializer
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializerProvider
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import space.nstart.pcp.pcp_types_lib.utils.UtcDateTimes
import java.time.LocalDateTime

@Configuration
class Jackson2UtcConfiguration {

    @Bean
    fun jackson2ObjectMapper(): ObjectMapper = jacksonObjectMapper()
        .findAndRegisterModules()
        .registerModule(utcLocalDateTimeModule())
}

private fun utcLocalDateTimeModule(): SimpleModule = SimpleModule("pcp-mission-planing-service-jackson2-utc-local-date-time")
    .addSerializer(LocalDateTime::class.java, Jackson2UtcLocalDateTimeSerializer())
    .addDeserializer(LocalDateTime::class.java, Jackson2UtcLocalDateTimeDeserializer())

private class Jackson2UtcLocalDateTimeSerializer : JsonSerializer<LocalDateTime>() {
    override fun serialize(value: LocalDateTime, gen: JsonGenerator, serializers: SerializerProvider) {
        gen.writeString(UtcDateTimes.format(value))
    }
}

private class Jackson2UtcLocalDateTimeDeserializer : JsonDeserializer<LocalDateTime>() {
    override fun deserialize(p: JsonParser, ctxt: DeserializationContext): LocalDateTime {
        val value = p.valueAsString ?: throw IllegalArgumentException("Expected ISO-8601 UTC date-time string")
        return UtcDateTimes.parse(value)
    }
}
