/*
 * 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 android.annotation.NonNull;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.telephony.TelephonyManager;
import android.util.LocalLog;
import android.util.Pair;

import com.android.server.wifi.hotspot2.PasspointNetworkNominateHelper;
import com.android.server.wifi.util.WifiPermissionsUtil;

import java.util.List;

/**
 * This class is the WifiNetworkSelector.NetworkNominator implementation for
 * saved networks.
 */
public class SavedNetworkNominator implements WifiNetworkSelector.NetworkNominator {
    private static final String NAME = "SavedNetworkNominator";
    private final WifiConfigManager mWifiConfigManager;
    private final LocalLog mLocalLog;
    private final WifiCarrierInfoManager mWifiCarrierInfoManager;
    private final PasspointNetworkNominateHelper mPasspointNetworkNominateHelper;
    private final WifiPermissionsUtil mWifiPermissionsUtil;
    private final WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager;

    SavedNetworkNominator(WifiConfigManager configManager,
            PasspointNetworkNominateHelper nominateHelper, LocalLog localLog,
            WifiCarrierInfoManager wifiCarrierInfoManager,
            WifiPermissionsUtil wifiPermissionsUtil,
            WifiNetworkSuggestionsManager wifiNetworkSuggestionsManager) {
        mWifiConfigManager = configManager;
        mPasspointNetworkNominateHelper = nominateHelper;
        mLocalLog = localLog;
        mWifiCarrierInfoManager = wifiCarrierInfoManager;
        mWifiPermissionsUtil = wifiPermissionsUtil;
        mWifiNetworkSuggestionsManager = wifiNetworkSuggestionsManager;
    }

    private void localLog(String log) {
        mLocalLog.log(log);
    }

    /**
     * Get the Nominator type.
     */
    @Override
    public @NominatorId int getId() {
        return NOMINATOR_ID_SAVED;
    }

    /**
     * Get the Nominator name.
     */
    @Override
    public String getName() {
        return NAME;
    }

    /**
     * Update the Nominator.
     */
    @Override
    public void update(List<ScanDetail> scanDetails) {
        // Update the matching profiles into WifiConfigManager, help displaying Passpoint networks
        // in Wifi Picker
        mPasspointNetworkNominateHelper.getPasspointNetworkCandidates(scanDetails, false);
    }

    /**
     * Run through all scanDetails and nominate all connectable network as candidates.
     *
     */
    @Override
    public void nominateNetworks(List<ScanDetail> scanDetails,
                    boolean untrustedNetworkAllowed /* unused */,
                    boolean oemPaidNetworkAllowed /* unused */,
                    boolean oemPrivateNetworkAllowed /* unused */,
            @NonNull OnConnectableListener onConnectableListener) {
        findMatchedSavedNetworks(scanDetails, onConnectableListener);
        findMatchedPasspointNetworks(scanDetails, onConnectableListener);
    }

    private void findMatchedSavedNetworks(List<ScanDetail> scanDetails,
            OnConnectableListener onConnectableListener) {
        for (ScanDetail scanDetail : scanDetails) {
            ScanResult scanResult = scanDetail.getScanResult();

            // One ScanResult can be associated with more than one network, hence we calculate all
            // the scores and use the highest one as the ScanResult's score.
            WifiConfiguration network =
                    mWifiConfigManager.getSavedNetworkForScanDetailAndCache(scanDetail);

            if (network == null) {
                continue;
            }

            /**
             * Ignore Passpoint and Ephemeral networks. They are configured networks,
             * but without being persisted to the storage. They are nominated by
             * {@link PasspointNetworkNominator} and {@link ScoredNetworkNominator}
             * respectively.
             */
            if (network.isPasspoint() || network.isEphemeral()) {
                continue;
            }

            // Ignore networks that the user has disallowed auto-join for.
            if (!network.allowAutojoin) {
                localLog("Ignoring auto join disabled SSID: " + network.SSID);
                continue;
            }

            WifiConfiguration.NetworkSelectionStatus status =
                    network.getNetworkSelectionStatus();
            status.setSeenInLastQualifiedNetworkSelection(true);

            if (mWifiConfigManager.isNonCarrierMergedNetworkTemporarilyDisabled(network)) {
                localLog("Ignoring non-carrier-merged SSID: " + network.SSID);
                continue;
            }
            if (mWifiConfigManager.isNetworkTemporarilyDisabledByUser(network.SSID)) {
                localLog("Ignoring user disabled SSID: " + network.SSID);
                continue;
            }

            if (!status.isNetworkEnabled()) {
                localLog("Ignoring network selection disabled SSID: " + network.SSID);
                continue;
            }
            if (network.BSSID != null &&  !network.BSSID.equals("any")
                    && !network.BSSID.equals(scanResult.BSSID)) {
                // App has specified the only BSSID to connect for this
                // configuration. So only the matching ScanResult can be a candidate.
                localLog("Network " + WifiNetworkSelector.toNetworkString(network)
                        + " has specified BSSID " + network.BSSID + ". Skip "
                        + scanResult.BSSID);
                continue;
            }
            if (isNetworkSimBasedCredential(network) && !isSimBasedNetworkAbleToAutoJoin(network)) {
                localLog("Ignoring SIM auto join disabled SSID: " + network.SSID);
                continue;
            }

            // If the network is marked to use external scores, or is an open network with
            // curate saved open networks enabled, do not consider it for network selection.
            if (network.useExternalScores) {
                localLog("Network " + WifiNetworkSelector.toNetworkString(network)
                        + " has external score.");
                continue;
            }

            if (mWifiNetworkSuggestionsManager
                    .shouldBeIgnoredBySecureSuggestionFromSameCarrier(network,
                            scanDetails)) {
                localLog("Open Network " + WifiNetworkSelector.toNetworkString(network)
                        + " has a secure network suggestion from same carrier.");
                continue;
            }

            onConnectableListener.onConnectable(scanDetail,
                    mWifiConfigManager.getConfiguredNetwork(network.networkId));
        }
    }

    private void findMatchedPasspointNetworks(List<ScanDetail> scanDetails,
            OnConnectableListener onConnectableListener) {
        List<Pair<ScanDetail, WifiConfiguration>> candidates =
                mPasspointNetworkNominateHelper.getPasspointNetworkCandidates(scanDetails, false);
        for (Pair<ScanDetail, WifiConfiguration> candidate : candidates) {
            WifiConfiguration config = candidate.second;
            if (!config.allowAutojoin) {
                continue;
            }
            if (isNetworkSimBasedCredential(config) && !isSimBasedNetworkAbleToAutoJoin(config)) {
                continue;
            }
            onConnectableListener.onConnectable(candidate.first, config);
        }
    }

    private boolean isSimBasedNetworkAbleToAutoJoin(WifiConfiguration network) {
        int carrierId = network.carrierId == TelephonyManager.UNKNOWN_CARRIER_ID
                ? mWifiCarrierInfoManager.getDefaultDataSimCarrierId() : network.carrierId;
        int subId = mWifiCarrierInfoManager.getMatchingSubId(carrierId);
        // Ignore security type is EAP SIM/AKA/AKA' when SIM is not present.
        if (!mWifiCarrierInfoManager.isSimReady(subId)) {
            localLog("No SIM card is good for Network "
                    + WifiNetworkSelector.toNetworkString(network));
            return false;
        }
        // Ignore IMSI info not available or protection exemption pending network.
        if (mWifiCarrierInfoManager.requiresImsiEncryption(subId)) {
            if (!mWifiCarrierInfoManager.isImsiEncryptionInfoAvailable(subId)) {
                localLog("Imsi protection required but not available for Network "
                        + WifiNetworkSelector.toNetworkString(network));
                return false;
            }
        } else if (isImsiProtectionApprovalNeeded(network.creatorUid, carrierId)) {
            localLog("Imsi protection exemption needed for Network "
                    + WifiNetworkSelector.toNetworkString(network));
            return false;
        }
        // Ignore metered network with non-data Sim.
        if (WifiConfiguration.isMetered(network, null)
                && mWifiCarrierInfoManager.isCarrierNetworkFromNonDefaultDataSim(network)) {
            localLog("No default SIM is used for metered Network: "
                    + WifiNetworkSelector.toNetworkString(network));
            return false;
        }
        return true;
    }

    private boolean isNetworkSimBasedCredential(WifiConfiguration network) {
        return network != null && network.enterpriseConfig != null
                && network.enterpriseConfig.isAuthenticationSimBased();
    }

    private boolean isImsiProtectionApprovalNeeded(int creatorUid, int carrierId) {
        // User saved network got exemption.
        if (mWifiPermissionsUtil.checkNetworkSettingsPermission(creatorUid)
                || mWifiPermissionsUtil.checkNetworkSetupWizardPermission(creatorUid)) {
            return false;
        }
        if (mWifiCarrierInfoManager.hasUserApprovedImsiPrivacyExemptionForCarrier(carrierId)) {
            return false;
        }
        mWifiCarrierInfoManager.sendImsiProtectionExemptionNotificationIfRequired(carrierId);
        return true;
    }
}
