/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.wifi;

import static org.junit.Assert.*;

import android.net.IpConfiguration;
import android.net.LinkAddress;
import android.net.NetworkUtils;
import android.net.ProxyInfo;
import android.net.StaticIpConfiguration;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiSsid;
import android.text.TextUtils;

import java.net.InetAddress;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.List;

/**
 * Helper for creating and populating WifiConfigurations in unit tests.
 */
public class WifiConfigurationTestUtil {
    /**
     * These values are used to describe AP's security setting. One AP can support multiple of them,
     * only if there is no conflict.
     */
    public static final int SECURITY_NONE = 0;
    public static final int SECURITY_WEP =  1 << 0;
    public static final int SECURITY_PSK =  1 << 1;
    public static final int SECURITY_EAP =  1 << 2;

    /**
     * These values are used to describe ip configuration parameters for a network.
     */
    public static final int STATIC_IP_ASSIGNMENT = 0;
    public static final int DHCP_IP_ASSIGNMENT = 1;
    public static final int STATIC_PROXY_SETTING = 0;
    public static final int PAC_PROXY_SETTING = 1;
    public static final int NONE_PROXY_SETTING = 2;

    /**
     * These are constants used to generate predefined WifiConfiguration objects.
     */
    public static final int TEST_NETWORK_ID = -1;
    public static final int TEST_UID = 5;
    public static final String TEST_SSID = "WifiConfigurationTestUtilSSID";
    public static final String TEST_PSK = "\"WifiConfigurationTestUtilPsk\"";
    public static final String[] TEST_WEP_KEYS =
            {"\"WifiConfigurationTestUtilWep1\"", "\"WifiConfigurationTestUtilWep2\"",
                    "45342312ab", "45342312ab45342312ab34ac12"};
    public static final String TEST_EAP_PASSWORD = "WifiConfigurationTestUtilEapPassword";
    public static final int TEST_WEP_TX_KEY_INDEX = 1;
    public static final String TEST_FQDN = "WifiConfigurationTestUtilFQDN";
    public static final String TEST_PROVIDER_FRIENDLY_NAME =
            "WifiConfigurationTestUtilFriendlyName";
    public static final String TEST_STATIC_IP_LINK_ADDRESS = "192.168.48.2";
    public static final int TEST_STATIC_IP_LINK_PREFIX_LENGTH = 8;
    public static final String TEST_STATIC_IP_GATEWAY_ADDRESS = "192.168.48.1";
    public static final String[] TEST_STATIC_IP_DNS_SERVER_ADDRESSES =
            new String[]{"192.168.48.1", "192.168.48.10"};
    public static final String TEST_STATIC_PROXY_HOST = "192.168.48.1";
    public static final int TEST_STATIC_PROXY_PORT = 8000;
    public static final String TEST_STATIC_PROXY_EXCLUSION_LIST = "";
    public static final String TEST_PAC_PROXY_LOCATION = "http://";
    public static final String TEST_CA_CERT_ALIAS = "WifiConfigurationTestUtilCaCertAlias";

    private static final int MAX_SSID_LENGTH = 32;
    /**
     * Index used to assign unique SSIDs for the generation of predefined WifiConfiguration objects.
     */
    private static int sNetworkIndex = 0;

    /**
     * Construct a {@link android.net.wifi.WifiConfiguration}.
     * @param networkId the configuration's networkId
     * @param uid the configuration's creator uid
     * @param ssid the configuration's ssid
     * @param shared whether the configuration is shared with other users on the device
     * @param enabled whether the configuration is enabled
     * @param fqdn the configuration's FQDN (Hotspot 2.0 only)
     * @param providerFriendlyName the configuration's provider's friendly name (Hotspot 2.0 only)
     * @return the constructed {@link android.net.wifi.WifiConfiguration}
     */
    public static WifiConfiguration generateWifiConfig(int networkId, int uid, String ssid,
            boolean shared, boolean enabled, String fqdn, String providerFriendlyName) {
        final WifiConfiguration config = new WifiConfiguration();
        config.SSID = ssid;
        config.networkId = networkId;
        config.creatorUid = uid;
        config.shared = shared;
        config.status = enabled ? WifiConfiguration.Status.ENABLED
                : WifiConfiguration.Status.DISABLED;
        config.FQDN = fqdn;
        config.providerFriendlyName = providerFriendlyName;
        return config;
    }

    /**
     * Construct a {@link android.net.wifi.WifiConfiguration}.
     * @param networkId the configuration's networkId
     * @param uid the configuration's creator uid
     * @param ssid the configuration's ssid
     * @param shared whether the configuration is shared with other users on the device
     * @param enabled whether the configuration is enabled
     * @param fqdn the configuration's FQDN (Hotspot 2.0 only)
     * @param providerFriendlyName the configuration's provider's friendly name (Hotspot 2.0 only)
     * @param security the configuration's security type
     * @return the constructed {@link android.net.wifi.WifiConfiguration}
     */
    public static WifiConfiguration generateWifiConfig(int networkId, int uid, String ssid,
            boolean shared, boolean enabled, String fqdn, String providerFriendlyName,
            int security) {
        WifiConfiguration config = generateWifiConfig(networkId, uid, ssid, shared, enabled, fqdn,
                providerFriendlyName);

        if ((security == SECURITY_NONE) || ((security & SECURITY_WEP) != 0)) {
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
        } else {
            if ((security & SECURITY_PSK) != 0) {
                config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
            }

            if ((security & SECURITY_EAP) != 0) {
                config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
                config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
                config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS);
            }
        }
        return config;
    }

    /**
     * Construct a {@link android.net.IpConfiguration }.
     * @param ipAssignmentType One of {@link #STATIC_IP_ASSIGNMENT} or {@link #DHCP_IP_ASSIGNMENT}.
     * @param proxySettingType One of {@link #STATIC_PROXY_SETTING} or {@link #PAC_PROXY_SETTING} or
     *                        {@link #NONE_PROXY_SETTING}.
     * @param linkAddress static ip address string.
     * @param linkPrefixLength static ip address prefix length.
     * @param gatewayAddress static gateway address.
     * @param dnsServerAddresses list of dns servers for static ip configuration.
     * @param proxyHost Static proxy server address.
     * @param proxyPort Static proxy server port.
     * @param proxyExclusionList Static proxy exclusion list.
     * @param pacProxyPath Pac proxy server path.
     * @return the constructed {@link android.net.IpConfiguration}
     */
    public static IpConfiguration generateIpConfig(
            int ipAssignmentType, int proxySettingType, String linkAddress, int linkPrefixLength,
            String gatewayAddress, String[] dnsServerAddresses, String proxyHost,
            int proxyPort, String proxyExclusionList, String pacProxyPath) {
        StaticIpConfiguration staticIpConfiguration = null;
        ProxyInfo proxyInfo = null;
        IpConfiguration.IpAssignment ipAssignment = IpConfiguration.IpAssignment.UNASSIGNED;
        IpConfiguration.ProxySettings proxySettings = IpConfiguration.ProxySettings.UNASSIGNED;

        if (ipAssignmentType == STATIC_IP_ASSIGNMENT) {
            staticIpConfiguration = new StaticIpConfiguration();
            if (!TextUtils.isEmpty(linkAddress)) {
                LinkAddress linkAddr =
                        new LinkAddress(
                                NetworkUtils.numericToInetAddress(linkAddress), linkPrefixLength);
                staticIpConfiguration.ipAddress = linkAddr;
            }

            if (!TextUtils.isEmpty(gatewayAddress)) {
                InetAddress gatewayAddr =
                        NetworkUtils.numericToInetAddress(gatewayAddress);
                staticIpConfiguration.gateway = gatewayAddr;
            }
            if (dnsServerAddresses != null) {
                for (String dnsServerAddress : dnsServerAddresses) {
                    if (!TextUtils.isEmpty(dnsServerAddress)) {
                        staticIpConfiguration.dnsServers.add(
                                NetworkUtils.numericToInetAddress(dnsServerAddress));
                    }

                }
            }
            ipAssignment = IpConfiguration.IpAssignment.STATIC;
        } else if (ipAssignmentType == DHCP_IP_ASSIGNMENT) {
            ipAssignment = IpConfiguration.IpAssignment.DHCP;
        }

        if (proxySettingType == STATIC_PROXY_SETTING) {
            proxyInfo = new ProxyInfo(proxyHost, proxyPort, proxyExclusionList);
            proxySettings = IpConfiguration.ProxySettings.STATIC;
        } else if (proxySettingType == PAC_PROXY_SETTING) {
            proxyInfo = new ProxyInfo(pacProxyPath);
            proxySettings = IpConfiguration.ProxySettings.PAC;
        } else if (proxySettingType == NONE_PROXY_SETTING) {
            proxySettings = IpConfiguration.ProxySettings.NONE;
        }
        return new IpConfiguration(ipAssignment, proxySettings, staticIpConfiguration, proxyInfo);
    }

    /**
     * Create a new SSID for the the network being created.
     */
    private static String createNewSSID() {
        String ssid = TEST_SSID + sNetworkIndex++;
        assertTrue(ssid.length() <= MAX_SSID_LENGTH);
        return "\"" + ssid + "\"";
    }

    /**
     * Helper methods to generate predefined WifiConfiguration objects of the required type. These
     * use a static index to avoid duplicate configurations.
     */
    public static WifiConfiguration createOpenNetwork() {
        return generateWifiConfig(TEST_NETWORK_ID, TEST_UID, createNewSSID(), true, true, null,
                null, SECURITY_NONE);
    }

    public static WifiConfiguration createEphemeralNetwork() {
        WifiConfiguration configuration = createOpenNetwork();
        configuration.ephemeral = true;
        return configuration;
    }

    public static WifiConfiguration createOpenHiddenNetwork() {
        WifiConfiguration configuration = createOpenNetwork();
        configuration.hiddenSSID = true;
        return configuration;
    }

    public static WifiConfiguration createPskNetwork() {
        WifiConfiguration configuration =
                generateWifiConfig(TEST_NETWORK_ID, TEST_UID, createNewSSID(), true, true, null,
                        null, SECURITY_PSK);
        configuration.preSharedKey = TEST_PSK;
        return configuration;
    }

    public static WifiConfiguration createPskNetwork(String ssid) {
        WifiConfiguration configuration =
                generateWifiConfig(TEST_NETWORK_ID, TEST_UID, ssid, true, true, null,
                        null, SECURITY_PSK);
        configuration.preSharedKey = TEST_PSK;
        return configuration;
    }


    public static WifiConfiguration createPskHiddenNetwork() {
        WifiConfiguration configuration = createPskNetwork();
        configuration.hiddenSSID = true;
        return configuration;
    }

    public static WifiConfiguration createWepNetwork() {
        WifiConfiguration configuration =
                generateWifiConfig(TEST_NETWORK_ID, TEST_UID, createNewSSID(), true, true, null,
                        null, SECURITY_WEP);
        configuration.wepKeys = TEST_WEP_KEYS;
        configuration.wepTxKeyIndex = TEST_WEP_TX_KEY_INDEX;
        return configuration;
    }

    public static WifiConfiguration createWepHiddenNetwork() {
        WifiConfiguration configuration = createWepNetwork();
        configuration.hiddenSSID = true;
        return configuration;
    }


    public static WifiConfiguration createWepNetworkWithSingleKey() {
        WifiConfiguration configuration =
                generateWifiConfig(TEST_NETWORK_ID, TEST_UID, createNewSSID(), true, true, null,
                        null, SECURITY_WEP);
        configuration.wepKeys[0] = TEST_WEP_KEYS[0];
        configuration.wepTxKeyIndex = 0;
        return configuration;
    }


    public static WifiConfiguration createEapNetwork() {
        WifiConfiguration configuration =
                generateWifiConfig(TEST_NETWORK_ID, TEST_UID, createNewSSID(), true, true,
                        null, null, SECURITY_EAP);
        return configuration;
    }

    public static WifiConfiguration createEapNetwork(String ssid) {
        WifiConfiguration configuration =
                generateWifiConfig(TEST_NETWORK_ID, TEST_UID, ssid, true, true,
                        null, null, SECURITY_EAP);
        return configuration;
    }


    public static WifiConfiguration createEapNetwork(int eapMethod, int phase2Method) {
        WifiConfiguration configuration =
                generateWifiConfig(TEST_NETWORK_ID, TEST_UID, createNewSSID(), true, true,
                        null, null, SECURITY_EAP);
        configuration.enterpriseConfig.setEapMethod(eapMethod);
        configuration.enterpriseConfig.setPhase2Method(phase2Method);
        return configuration;
    }

    public static WifiConfiguration createPasspointNetwork() {
        WifiConfiguration configuration =
                generateWifiConfig(TEST_NETWORK_ID, TEST_UID, createNewSSID(), true, true,
                        TEST_FQDN, TEST_PROVIDER_FRIENDLY_NAME, SECURITY_EAP);
        return configuration;
    }

    public static IpConfiguration createStaticIpConfigurationWithPacProxy() {
        return generateIpConfig(
                STATIC_IP_ASSIGNMENT, PAC_PROXY_SETTING,
                TEST_STATIC_IP_LINK_ADDRESS, TEST_STATIC_IP_LINK_PREFIX_LENGTH,
                TEST_STATIC_IP_GATEWAY_ADDRESS, TEST_STATIC_IP_DNS_SERVER_ADDRESSES,
                TEST_STATIC_PROXY_HOST, TEST_STATIC_PROXY_PORT, TEST_STATIC_PROXY_EXCLUSION_LIST,
                TEST_PAC_PROXY_LOCATION);
    }

    public static IpConfiguration createStaticIpConfigurationWithStaticProxy() {
        return generateIpConfig(
                STATIC_IP_ASSIGNMENT, STATIC_PROXY_SETTING,
                TEST_STATIC_IP_LINK_ADDRESS, TEST_STATIC_IP_LINK_PREFIX_LENGTH,
                TEST_STATIC_IP_GATEWAY_ADDRESS, TEST_STATIC_IP_DNS_SERVER_ADDRESSES,
                TEST_STATIC_PROXY_HOST, TEST_STATIC_PROXY_PORT, TEST_STATIC_PROXY_EXCLUSION_LIST,
                TEST_PAC_PROXY_LOCATION);
    }

    public static IpConfiguration createPartialStaticIpConfigurationWithPacProxy() {
        return generateIpConfig(
                STATIC_IP_ASSIGNMENT, PAC_PROXY_SETTING,
                TEST_STATIC_IP_LINK_ADDRESS, TEST_STATIC_IP_LINK_PREFIX_LENGTH,
                null, null,
                TEST_STATIC_PROXY_HOST, TEST_STATIC_PROXY_PORT, TEST_STATIC_PROXY_EXCLUSION_LIST,
                TEST_PAC_PROXY_LOCATION);
    }

    public static IpConfiguration createDHCPIpConfigurationWithPacProxy() {
        return generateIpConfig(
                DHCP_IP_ASSIGNMENT, PAC_PROXY_SETTING,
                TEST_STATIC_IP_LINK_ADDRESS, TEST_STATIC_IP_LINK_PREFIX_LENGTH,
                TEST_STATIC_IP_GATEWAY_ADDRESS, TEST_STATIC_IP_DNS_SERVER_ADDRESSES,
                TEST_STATIC_PROXY_HOST, TEST_STATIC_PROXY_PORT, TEST_STATIC_PROXY_EXCLUSION_LIST,
                TEST_PAC_PROXY_LOCATION);
    }

    public static IpConfiguration createDHCPIpConfigurationWithStaticProxy() {
        return generateIpConfig(
                DHCP_IP_ASSIGNMENT, STATIC_PROXY_SETTING,
                TEST_STATIC_IP_LINK_ADDRESS, TEST_STATIC_IP_LINK_PREFIX_LENGTH,
                TEST_STATIC_IP_GATEWAY_ADDRESS, TEST_STATIC_IP_DNS_SERVER_ADDRESSES,
                TEST_STATIC_PROXY_HOST, TEST_STATIC_PROXY_PORT, TEST_STATIC_PROXY_EXCLUSION_LIST,
                TEST_PAC_PROXY_LOCATION);
    }

    public static IpConfiguration createDHCPIpConfigurationWithNoProxy() {
        return generateIpConfig(
                DHCP_IP_ASSIGNMENT, NONE_PROXY_SETTING,
                TEST_STATIC_IP_LINK_ADDRESS, TEST_STATIC_IP_LINK_PREFIX_LENGTH,
                TEST_STATIC_IP_GATEWAY_ADDRESS, TEST_STATIC_IP_DNS_SERVER_ADDRESSES,
                TEST_STATIC_PROXY_HOST, TEST_STATIC_PROXY_PORT, TEST_STATIC_PROXY_EXCLUSION_LIST,
                TEST_PAC_PROXY_LOCATION);
    }

    /**
     * Creates an IP configuration with specific parameters.
     * @param proxySetting Must be one of {@link WifiConfigurationTestUtil#STATIC_PROXY_SETTING},
     * {@link WifiConfigurationTestUtil#PAC_PROXY_SETTING},
     * {@link WifiConfigurationTestUtil#NONE_PROXY_SETTING}
     */
    public static IpConfiguration createDHCPIpConfigurationWithSpecificProxy(
            int proxySetting,
            String staticProxyHost,
            int staticProxyPort,
            String staticProxyExclusionList,
            String pacProxyLocation) {
        return generateIpConfig(
                DHCP_IP_ASSIGNMENT, proxySetting,
                TEST_STATIC_IP_LINK_ADDRESS, TEST_STATIC_IP_LINK_PREFIX_LENGTH,
                TEST_STATIC_IP_GATEWAY_ADDRESS, TEST_STATIC_IP_DNS_SERVER_ADDRESSES,
                staticProxyHost, staticProxyPort, staticProxyExclusionList,
                pacProxyLocation);
    }

    // TODO: These enterprise configurations may need more parameters set.
    public static WifiEnterpriseConfig createPEAPWifiEnterpriseConfigWithGTCPhase2() {
        WifiEnterpriseConfig config = new WifiEnterpriseConfig();
        config.setEapMethod(WifiEnterpriseConfig.Eap.PEAP);
        config.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
        config.setCaCertificateAliases(new String[] {TEST_CA_CERT_ALIAS + "PEAP"});
        config.setCaCertificates(new X509Certificate[] {FakeKeys.CA_CERT0, FakeKeys.CA_CERT1});
        return config;
    }

    public static WifiEnterpriseConfig createTLSWifiEnterpriseConfigWithNonePhase2() {
        WifiEnterpriseConfig config = new WifiEnterpriseConfig();
        config.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
        config.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE);
        config.setCaCertificateAliases(new String[] {TEST_CA_CERT_ALIAS + "TLS"});
        config.setCaCertificates(new X509Certificate[] {FakeKeys.CA_CERT0, FakeKeys.CA_CERT1});
        return config;
    }

    public static WifiEnterpriseConfig createTLSWifiEnterpriseConfigWithAkaPhase2() {
        WifiEnterpriseConfig config = new WifiEnterpriseConfig();
        config.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
        config.setPhase2Method(WifiEnterpriseConfig.Phase2.AKA);
        return config;
    }

    /**
     * Creates a scan detail corresponding to the provided network and given BSSID, level &frequency
     * values.
     */
    public static ScanDetail createScanDetailForNetwork(
            WifiConfiguration configuration, String bssid, int level, int frequency,
            long tsf, long seen) {
        String caps;
        if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK)) {
            caps = "[WPA2-PSK-CCMP]";
        } else if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP)
                || configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X)) {
            caps = "[WPA2-EAP-CCMP]";
        } else if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)
                && WifiConfigurationUtil.hasAnyValidWepKey(configuration.wepKeys)) {
            caps = "[WEP]";
        } else {
            caps = "[]";
        }
        WifiSsid ssid = WifiSsid.createFromAsciiEncoded(configuration.getPrintableSsid());
        return new ScanDetail(ssid, bssid, caps, level, frequency, tsf, seen);
    }

    /**
     * Asserts that the 2 WifiConfigurations are equal in the elements saved for both backup/restore
     * and config store.
     */
    private static void assertCommonConfigurationElementsEqual(
            WifiConfiguration expected, WifiConfiguration actual) {
        assertNotNull(expected);
        assertNotNull(actual);
        assertEquals(expected.SSID, actual.SSID);
        assertEquals(expected.BSSID, actual.BSSID);
        assertEquals(expected.preSharedKey, actual.preSharedKey);
        assertEquals(expected.wepKeys, actual.wepKeys);
        assertEquals(expected.wepTxKeyIndex, actual.wepTxKeyIndex);
        assertEquals(expected.hiddenSSID, actual.hiddenSSID);
        assertEquals(expected.requirePMF, actual.requirePMF);
        assertEquals(expected.allowedKeyManagement, actual.allowedKeyManagement);
        assertEquals(expected.allowedProtocols, actual.allowedProtocols);
        assertEquals(expected.allowedAuthAlgorithms, actual.allowedAuthAlgorithms);
        assertEquals(expected.allowedGroupCiphers, actual.allowedGroupCiphers);
        assertEquals(expected.allowedPairwiseCiphers, actual.allowedPairwiseCiphers);
        assertEquals(expected.shared, actual.shared);
        assertEquals(expected.getIpConfiguration(), actual.getIpConfiguration());
    }

    /**
     * Asserts that the 2 WifiConfigurations are equal. This only compares the elements saved
     * fpr backup/restore.
     */
    public static void assertConfigurationEqualForBackup(
            WifiConfiguration expected, WifiConfiguration actual) {
        assertCommonConfigurationElementsEqual(expected, actual);
    }

    /**
     * Asserts that the 2 WifiConfigurations are equal. This compares all the elements saved for
     * config store.
     */
    public static void assertConfigurationEqualForConfigStore(
            WifiConfiguration expected, WifiConfiguration actual) {
        assertCommonConfigurationElementsEqual(expected, actual);
        assertEquals(expected.status, actual.status);
        assertEquals(expected.FQDN, actual.FQDN);
        assertEquals(expected.providerFriendlyName, actual.providerFriendlyName);
        assertTrue(Arrays.equals(expected.roamingConsortiumIds, actual.roamingConsortiumIds));
        assertEquals(expected.linkedConfigurations, actual.linkedConfigurations);
        assertEquals(expected.defaultGwMacAddress, actual.defaultGwMacAddress);
        assertEquals(expected.validatedInternetAccess, actual.validatedInternetAccess);
        assertEquals(expected.noInternetAccessExpected, actual.noInternetAccessExpected);
        assertEquals(expected.userApproved, actual.userApproved);
        assertEquals(expected.meteredHint, actual.meteredHint);
        assertEquals(expected.useExternalScores, actual.useExternalScores);
        assertEquals(expected.numAssociation, actual.numAssociation);
        assertEquals(expected.creatorUid, actual.creatorUid);
        assertEquals(expected.creatorName, actual.creatorName);
        assertEquals(expected.creationTime, actual.creationTime);
        assertEquals(expected.lastUpdateUid, actual.lastUpdateUid);
        assertEquals(expected.lastUpdateName, actual.lastUpdateName);
        assertEquals(expected.lastConnectUid, actual.lastConnectUid);
        assertEquals(expected.updateTime, actual.updateTime);
        assertEquals(expected.isLegacyPasspointConfig, actual.isLegacyPasspointConfig);
        assertNetworkSelectionStatusEqualForConfigStore(
                expected.getNetworkSelectionStatus(), actual.getNetworkSelectionStatus());
        assertWifiEnterpriseConfigEqualForConfigStore(
                expected.enterpriseConfig, actual.enterpriseConfig);
    }

    /**
     * Asserts that the 2 WifiConfigurations are equal. This compares all the elements that are
     * saved into internal database by WifiConfigurationManager for network additions/updates.
     */
    public static void assertConfigurationEqualForConfigManagerAddOrUpdate(
            WifiConfiguration expected, WifiConfiguration actual) {
        assertCommonConfigurationElementsEqual(expected, actual);
        assertEquals(expected.FQDN, actual.FQDN);
        assertEquals(expected.providerFriendlyName, actual.providerFriendlyName);
        assertEquals(expected.noInternetAccessExpected, actual.noInternetAccessExpected);
        assertEquals(expected.meteredHint, actual.meteredHint);
        assertEquals(expected.useExternalScores, actual.useExternalScores);
        assertEquals(expected.ephemeral, actual.ephemeral);
        assertEquals(expected.creatorUid, actual.creatorUid);
        assertEquals(expected.creatorName, actual.creatorName);
        assertEquals(expected.creationTime, actual.creationTime);
        assertEquals(expected.lastUpdateUid, actual.lastUpdateUid);
        assertEquals(expected.lastUpdateName, actual.lastUpdateName);
        assertEquals(expected.updateTime, actual.updateTime);
        assertNetworkSelectionStatusEqualForConfigStore(
                expected.getNetworkSelectionStatus(), actual.getNetworkSelectionStatus());
        assertWifiEnterpriseConfigEqualForConfigStore(
                expected.enterpriseConfig, actual.enterpriseConfig);
    }

    /**
     * Asserts that the 2 WifiConfigurations are equal. This compares all the elements that are
     * saved into wpa_supplicant by SupplicantStaNetwork.
     */
    public static void assertConfigurationEqualForSupplicant(
            WifiConfiguration expected, WifiConfiguration actual) {
        assertNotNull(expected);
        assertNotNull(actual);
        assertEquals(expected.SSID, actual.SSID);
        assertEquals(expected.getNetworkSelectionStatus().getNetworkSelectionBSSID(),
                actual.getNetworkSelectionStatus().getNetworkSelectionBSSID());
        assertEquals(expected.preSharedKey, actual.preSharedKey);
        assertEquals(expected.wepKeys, actual.wepKeys);
        assertEquals(expected.wepTxKeyIndex, actual.wepTxKeyIndex);
        assertEquals(expected.hiddenSSID, actual.hiddenSSID);
        assertEquals(expected.requirePMF, actual.requirePMF);
        assertEquals(expected.allowedKeyManagement, actual.allowedKeyManagement);
        assertEquals(expected.allowedProtocols, actual.allowedProtocols);
        assertEquals(expected.allowedAuthAlgorithms, actual.allowedAuthAlgorithms);
        assertEquals(expected.allowedGroupCiphers, actual.allowedGroupCiphers);
        assertEquals(expected.allowedPairwiseCiphers, actual.allowedPairwiseCiphers);
        assertWifiEnterpriseConfigEqualForConfigStore(
                expected.enterpriseConfig, actual.enterpriseConfig);
    }

    /**
     * Asserts that the 2 WifiConfigurations are equal. This is a generic version of the comparator
     * which is used in QNS tests for comparing the network selections.
     * This importantly checks that the networkId's of the 2 configs are equal.
     */
    public static void assertConfigurationEqual(
            WifiConfiguration expected, WifiConfiguration actual) {
        assertCommonConfigurationElementsEqual(expected, actual);
        assertEquals(expected.networkId, actual.networkId);
    }

    /**
     * Assert that the 2 NetworkSelectionStatus's are equal. This compares all the elements saved
     * for config store.
     */
    public static void assertNetworkSelectionStatusEqualForConfigStore(
            NetworkSelectionStatus expected, NetworkSelectionStatus actual) {
        if (expected.isNetworkTemporaryDisabled()) {
            // Temporarily disabled networks are enabled when persisted.
            assertEquals(
                    NetworkSelectionStatus.NETWORK_SELECTION_ENABLED,
                    actual.getNetworkSelectionStatus());
            assertEquals(
                    NetworkSelectionStatus.NETWORK_SELECTION_ENABLE,
                    actual.getNetworkSelectionDisableReason());
        } else {
            assertEquals(expected.getNetworkSelectionStatus(), actual.getNetworkSelectionStatus());
            assertEquals(
                    expected.getNetworkSelectionDisableReason(),
                    actual.getNetworkSelectionDisableReason());
        }
        assertEquals(expected.getConnectChoice(), actual.getConnectChoice());
        assertEquals(expected.getConnectChoiceTimestamp(), actual.getConnectChoiceTimestamp());
        assertEquals(expected.getHasEverConnected(), actual.getHasEverConnected());
    }

    /**
     * Assert that the 2 WifiEnterpriseConfig's are equal. This compares all the elements saved
     * for config store.
     */
    public static void assertWifiEnterpriseConfigEqualForConfigStore(
            WifiEnterpriseConfig expected, WifiEnterpriseConfig actual) {
        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.IDENTITY_KEY),
                actual.getFieldValue(WifiEnterpriseConfig.IDENTITY_KEY));
        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.ANON_IDENTITY_KEY),
                actual.getFieldValue(WifiEnterpriseConfig.ANON_IDENTITY_KEY));
        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.PASSWORD_KEY),
                actual.getFieldValue(WifiEnterpriseConfig.PASSWORD_KEY));
        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY),
                actual.getFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY));
        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.CA_CERT_KEY),
                actual.getFieldValue(WifiEnterpriseConfig.CA_CERT_KEY));
        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY),
                actual.getFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY));
        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.ENGINE_KEY),
                actual.getFieldValue(WifiEnterpriseConfig.ENGINE_KEY));
        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY),
                actual.getFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY));
        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY),
                actual.getFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY));
        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY),
                actual.getFieldValue(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY));
        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY),
                actual.getFieldValue(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY));
        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.CA_PATH_KEY),
                actual.getFieldValue(WifiEnterpriseConfig.CA_PATH_KEY));
        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.REALM_KEY),
                actual.getFieldValue(WifiEnterpriseConfig.REALM_KEY));
        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.PLMN_KEY),
                actual.getFieldValue(WifiEnterpriseConfig.PLMN_KEY));
        assertEquals(expected.getEapMethod(), actual.getEapMethod());
        assertEquals(expected.getPhase2Method(), actual.getPhase2Method());
    }

    /**
     * Asserts that the 2 lists of WifiConfigurations are equal. This compares all the elements
     * saved for backup/restore.
     */
    public static void assertConfigurationsEqualForBackup(
            List<WifiConfiguration> expected, List<WifiConfiguration> actual) {
        assertEquals(expected.size(), actual.size());
        for (WifiConfiguration expectedConfiguration : expected) {
            String expectedConfigKey = expectedConfiguration.configKey();
            boolean didCompare = false;
            for (WifiConfiguration actualConfiguration : actual) {
                String actualConfigKey = actualConfiguration.configKey();
                if (actualConfigKey.equals(expectedConfigKey)) {
                    assertConfigurationEqualForBackup(
                            expectedConfiguration, actualConfiguration);
                    didCompare = true;
                }
            }
            assertTrue(didCompare);
        }
    }

    /**
     * Asserts that the 2 lists of WifiConfigurations are equal. This compares all the elements
     * that are saved into internal database by WifiConfigurationManager for network
     * additions/updates.
     */
    public static void assertConfigurationsEqualForConfigManagerAddOrUpdate(
            List<WifiConfiguration> expected, List<WifiConfiguration> actual) {
        assertEquals(expected.size(), actual.size());
        for (WifiConfiguration expectedConfiguration : expected) {
            String expectedConfigKey = expectedConfiguration.configKey();
            boolean didCompare = false;
            for (WifiConfiguration actualConfiguration : actual) {
                String actualConfigKey = actualConfiguration.configKey();
                if (actualConfigKey.equals(expectedConfigKey)) {
                    assertConfigurationEqualForConfigManagerAddOrUpdate(
                            expectedConfiguration, actualConfiguration);
                    didCompare = true;
                }
            }
            assertTrue(didCompare);
        }
    }

    /**
     * Asserts that the 2 lists of WifiConfigurations are equal. This compares all the elements
     * saved for config store.
     */
    public static void assertConfigurationsEqualForConfigStore(
            List<WifiConfiguration> expected, List<WifiConfiguration> actual) {
        assertEquals(expected.size(), actual.size());
        for (WifiConfiguration expectedConfiguration : expected) {
            String expectedConfigKey = expectedConfiguration.configKey();
            boolean didCompare = false;
            for (WifiConfiguration actualConfiguration : actual) {
                String actualConfigKey = actualConfiguration.configKey();
                if (actualConfigKey.equals(expectedConfigKey)) {
                    assertConfigurationEqualForConfigStore(
                            expectedConfiguration, actualConfiguration);
                    didCompare = true;
                }
            }
            assertTrue(didCompare);
        }
    }
}
