package com.smartdevicelink.transport.utl;

import android.annotation.TargetApi;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.os.Build;

import java.io.IOException;
import java.net.Socket;

import javax.net.SocketFactory;

import static com.smartdevicelink.util.NativeLogTool.logInfo;

public class WiFiSocketFactory {
    /**
     * Creates a TCP socket which is bound to Wi-Fi network (for Android 5+)
     *
     * On Android 5 and later, this method returns a Socket which is always bound to a Wi-Fi
     * network. If the phone is not connected to a Wi-Fi network, this method throws an IOException.
     * Prior to Android 5, this method simply creates a Socket equivalent to "new Socket();".
     *
     * @return a Socket instance bound to Wi-Fi network.
     */
    public static Socket createSocket(Context context) throws IOException {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            SocketFactory factory = retrieveSocketFactory(context);
            if (factory == null) {
                logInfo("Cannot find Wi-Fi network, aborting socket creation.");
                throw new IOException("The phone is not connected to Wi-Fi network");
            }
            return factory.createSocket();
        } else {
            return new Socket();
        }
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private static SocketFactory retrieveSocketFactory(Context context) {
        ConnectivityManager connMan = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
        // requires ACCESS_NETWORK_STATE permission
        Network[] allNetworks = connMan.getAllNetworks();

        for (Network network : allNetworks) {
            // requires ACCESS_NETWORK_STATE permission
            NetworkCapabilities capabilities = connMan.getNetworkCapabilities(network);
            if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                return network.getSocketFactory();
            }
        }

        return null;
    }
}

@@ -297,41 +297,8 @@
 t;%0A%0A
-import javax.net.SocketFactory;%0A%0A
 impo
@@ -355,16 +355,16 @@
 ogInfo;%0A
+
 %0Apublic 
@@ -1008,47 +1008,34 @@
 cket
-Factory factory
+ socket
  = 
+c
 re
-trieveSocketFactory
+ateWiFiSocket
 (con
@@ -1057,23 +1057,22 @@
     if (
-factory
+socket
  == null
@@ -1279,30 +1279,14 @@
 urn 
-factory.createS
+s
 ocket
-()
 ;%0A  
@@ -1424,37 +1424,25 @@
 cket
-Factory retrieveSocketFactory
+ createWiFiSocket
 (Con
@@ -1683,16 +1683,362 @@
 rks();%0A%0A
+        // Samsung Galaxy S9 (with Android 8.0.0) provides two %60Network%60 instances which have%0A        // TRANSPORT_WIFI capability. The first one throws an IOException upon creating a Socket,%0A        // and the second one actually works. To support such case, here we iterate over all%0A        // %60Network%60 instances until we can create a Socket.%0A
         
@@ -2296,24 +2296,50 @@
 RT_WIFI)) %7B%0A
+                try %7B%0A    
             
@@ -2375,17 +2375,188 @@
 actory()
-;
+.createSocket();%0A                %7D catch (IOException e) %7B%0A                    logInfo(%22IOException during socket creation (ignored): %22 + e.getMessage());%0A                %7D
 %0A       

support Android system returning more than 1 Wi-Fi Networks