package de.duffy.screencast

import android.content.Context
import android.net.ConnectivityManager
import android.net.LinkAddress
import android.os.Build
import java.net.Inet4Address
import java.net.NetworkInterface

object NetworkUtil {

    /** Die IPv4-Adresse, unter der der Fernseher das Handy im WLAN erreicht. */
    fun localAddress(context: Context): String {
        fromConnectivityManager(context)?.let { return it }
        fromInterfaces()?.let { return it }
        return "127.0.0.1"
    }

    private fun fromConnectivityManager(context: Context): String? {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return null
        return try {
            val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
            val network = cm.activeNetwork ?: return null
            val props = cm.getLinkProperties(network) ?: return null
            props.linkAddresses
                .map(LinkAddress::getAddress)
                .filterIsInstance<Inet4Address>()
                .firstOrNull { !it.isLoopbackAddress }
                ?.hostAddress
        } catch (_: Exception) { null }
    }

    private fun fromInterfaces(): String? = try {
        NetworkInterface.getNetworkInterfaces().toList()
            .filter { it.isUp && !it.isLoopback }
            // WLAN und Hotspot zuerst - genau darueber laeuft die Uebertragung.
            .sortedBy { if (it.name.startsWith("wlan") || it.name.startsWith("ap")) 0 else 1 }
            .flatMap { it.inetAddresses.toList() }
            .filterIsInstance<Inet4Address>()
            .firstOrNull { !it.isLoopbackAddress }
            ?.hostAddress
    } catch (_: Exception) { null }

    /** Ist ueberhaupt ein WLAN aktiv? Ohne WLAN nuetzt der Stream wenig. */
    fun isOnWifi(context: Context): Boolean = try {
        val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val caps = cm.getNetworkCapabilities(cm.activeNetwork ?: return false) ?: return false
            caps.hasTransport(android.net.NetworkCapabilities.TRANSPORT_WIFI) ||
                caps.hasTransport(android.net.NetworkCapabilities.TRANSPORT_ETHERNET)
        } else true
    } catch (_: Exception) { true }
}
