package pragma.gameinstance.gamefabric

import pragma.gameinstance.GameFabricGameInstance
import pragma.logging.PragmaLoggerFactory

/** Query and store a list of ping servers in a GameFabric environment to use for testing latency between clients and game servers. */
class GameFabricRegionPingCache(
    val gameFabricApi: GameFabricApi,
) {
    private lateinit var supportedGameServerZones: Set<String>

    @Volatile
    private var _pingRegions: List<GameFabricGameInstance.PingRegion> = emptyList()

    val pingRegions: List<GameFabricGameInstance.PingRegion>
        get() = _pingRegions

    fun init(
        config: GameFabricApi.ApiConfig,
        supportedGameServerZones: Iterable<String>,
    ) {
        this.gameFabricApi.init(config)
        this.supportedGameServerZones = supportedGameServerZones.toSet()
    }

    /** Check if the cache has any ping server data. */
    fun isNotEmpty(): Boolean = pingRegions.isNotEmpty()

    /**
     * Call the GameFabric API to update the list of ping servers. Callers must invoke init() before updating ping servers
     * to initialize the API.
     */
    suspend fun updatePingServers() {
        val pingServerResponse = gameFabricApi.ping()
        _pingRegions =
            pingServerResponse
                .toProto(
                    gameFabricApi.config.gameServerZonesByProviderRegion.filter {
                        supportedGameServerZones.isEmpty() || supportedGameServerZones.contains(it.value)
                    }
                )
    }

    companion object {
        private val logger = PragmaLoggerFactory.getLogger(this::class)

        fun pingProtocolToProto(protocol: String): GameFabricGameInstance.PingProtocol =
            when (protocol.lowercase()) {
                "icmp" -> GameFabricGameInstance.PingProtocol.ICMP
                "udp" -> GameFabricGameInstance.PingProtocol.UDP
                "wss" -> GameFabricGameInstance.PingProtocol.WSS
                else -> GameFabricGameInstance.PingProtocol.UNRECOGNIZED.also { logger.error("Unsupported ping server protocol: $protocol") }
            }
    }
}
