/*
 * Copyright (C) 2022 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 android.jobscheduler.cts;

import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;

import static com.android.compatibility.common.util.TestUtils.waitUntil;

import static junit.framework.Assert.fail;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;

import android.Manifest;
import android.annotation.NonNull;
import android.app.Instrumentation;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.provider.Settings;
import android.util.Log;

import com.android.compatibility.common.util.CallbackAsserter;
import com.android.compatibility.common.util.ShellIdentityUtils;
import com.android.compatibility.common.util.SystemUtil;

import junit.framework.AssertionFailedError;

import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class NetworkingHelper {
    private static final String TAG = "JsNetworkingUtils";

    private static final String RESTRICT_BACKGROUND_GET_CMD =
            "cmd netpolicy get restrict-background";
    private static final String RESTRICT_BACKGROUND_ON_CMD =
            "cmd netpolicy set restrict-background true";
    private static final String RESTRICT_BACKGROUND_OFF_CMD =
            "cmd netpolicy set restrict-background false";

    private final Context mContext;
    private final Instrumentation mInstrumentation;

    private final ConnectivityManager mConnectivityManager;
    private final WifiManager mWifiManager;

    /** Whether the device running these tests supports WiFi. */
    private final boolean mHasWifi;
    /** Whether the device running these tests supports ethernet. */
    private final boolean mHasEthernet;
    /** Whether the device running these tests supports telephony. */
    private final boolean mHasTelephony;

    private final boolean mInitialAirplaneModeState;
    private final boolean mInitialDataSaverState;
    private final String mInitialLocationMode;
    private final boolean mInitialWiFiState;
    private String mInitialWiFiMeteredState;
    private String mInitialWiFiSSID;

    NetworkingHelper(@NonNull Instrumentation instrumentation, @NonNull Context context)
            throws Exception {
        mContext = context;
        mInstrumentation = instrumentation;

        mConnectivityManager = context.getSystemService(ConnectivityManager.class);
        mWifiManager = context.getSystemService(WifiManager.class);

        PackageManager packageManager = mContext.getPackageManager();
        mHasWifi = packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI);
        mHasEthernet = packageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET);
        mHasTelephony = packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);

        mInitialAirplaneModeState = isAirplaneModeOn();
        mInitialDataSaverState = isDataSaverEnabled();
        mInitialLocationMode = Settings.Secure.getString(
                mContext.getContentResolver(), Settings.Secure.LOCATION_MODE);
        mInitialWiFiState = mHasWifi && isWifiEnabled();
    }

    /** Ensures that the device has a wifi network saved. */
    void ensureSavedWifiNetwork() throws Exception {
        if (!mHasWifi) {
            return;
        }
        final List<WifiConfiguration> savedNetworks =
                ShellIdentityUtils.invokeMethodWithShellPermissions(
                        mWifiManager, WifiManager::getConfiguredNetworks);
        assertFalse("Need at least one saved wifi network", savedNetworks.isEmpty());

        setWifiState(true);
        if (mInitialWiFiSSID == null) {
            mInitialWiFiSSID = getWifiSSID();
            mInitialWiFiMeteredState = getWifiMeteredStatus(mInitialWiFiSSID);
        }
    }

    // Returns "true", "false", or "none".
    private String getWifiMeteredStatus(String ssid) {
        // Interestingly giving the SSID as an argument to list wifi-networks
        // only works iff the network in question has the "false" policy.
        // Also unfortunately runShellCommand does not pass the command to the interpreter
        // so it's not possible to | grep the ssid.
        final String command = "cmd netpolicy list wifi-networks";
        final String policyString = SystemUtil.runShellCommand(command);

        final Matcher m = Pattern.compile(ssid + ";(true|false|none)",
                Pattern.MULTILINE | Pattern.UNIX_LINES).matcher(policyString);
        if (!m.find()) {
            fail("Unexpected format from cmd netpolicy (when looking for " + ssid + "): "
                    + policyString);
        }
        return m.group(1);
    }

    @NonNull
    private String getWifiSSID() throws Exception {
        // Location needs to be enabled to get the WiFi information.
        setLocationMode(String.valueOf(Settings.Secure.LOCATION_MODE_ON));
        final AtomicReference<String> ssid = new AtomicReference<>();
        SystemUtil.runWithShellPermissionIdentity(
                () -> ssid.set(mWifiManager.getConnectionInfo().getSSID()),
                Manifest.permission.ACCESS_FINE_LOCATION);
        return unquoteSSID(ssid.get());
    }

    boolean hasEthernetConnection() {
        if (!mHasEthernet) return false;
        Network[] networks = mConnectivityManager.getAllNetworks();
        for (Network network : networks) {
            if (mConnectivityManager.getNetworkCapabilities(network)
                    .hasTransport(TRANSPORT_ETHERNET)) {
                return true;
            }
        }
        return false;
    }

    boolean hasWifiFeature() {
        return mHasWifi;
    }

    boolean isAirplaneModeOn() throws Exception {
        final String output = SystemUtil.runShellCommand(mInstrumentation,
                "cmd connectivity airplane-mode").trim();
        return "enabled".equals(output);
    }

    boolean isDataSaverEnabled() throws Exception {
        return SystemUtil
                .runShellCommand(mInstrumentation, RESTRICT_BACKGROUND_GET_CMD)
                .contains("enabled");
    }

    boolean isWiFiConnected() {
        if (!mWifiManager.isWifiEnabled()) {
            return false;
        }
        final Network network = mConnectivityManager.getActiveNetwork();
        if (network == null) {
            return false;
        }
        final NetworkCapabilities networkCapabilities =
                mConnectivityManager.getNetworkCapabilities(network);
        return networkCapabilities != null && networkCapabilities.hasTransport(TRANSPORT_WIFI);
    }

    boolean isWifiEnabled() {
        return mWifiManager.isWifiEnabled();
    }

    /**
     * Tries to set all network statuses to {@code enabled}.
     * However, this does not support ethernet connections.
     * Confirm that {@link #hasEthernetConnection()} returns false before relying on this.
     */
    void setAllNetworksEnabled(boolean enabled) throws Exception {
        if (mHasWifi) {
            setWifiState(enabled);
        }
        setAirplaneMode(!enabled);
    }

    void setAirplaneMode(boolean on) throws Exception {
        if (isAirplaneModeOn() == on) {
            return;
        }
        final CallbackAsserter airplaneModeBroadcastAsserter = CallbackAsserter.forBroadcast(
                new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));
        SystemUtil.runShellCommand(mInstrumentation,
                "cmd connectivity airplane-mode " + (on ? "enable" : "disable"));
        airplaneModeBroadcastAsserter.assertCalled("Didn't get airplane mode changed broadcast",
                15 /* 15 seconds */);
        if (!on && mHasWifi) {
            // Try to trigger some network connection.
            setWifiState(true);
        }
        waitUntil("Airplane mode didn't change to " + (on ? " on" : " off"), 60 /* seconds */,
                () -> {
                    // Airplane mode only affects the cellular network. If the device doesn't
                    // support cellular, then we can only check that the airplane mode toggle is on.
                    if (!mHasTelephony) {
                        return on == isAirplaneModeOn();
                    }
                    if (on) {
                        Network[] networks = mConnectivityManager.getAllNetworks();
                        for (Network network : networks) {
                            if (mConnectivityManager.getNetworkCapabilities(network)
                                    .hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                                return false;
                            }
                        }
                        return true;
                    } else {
                        return mConnectivityManager.getActiveNetwork() != null;
                    }
                });
        // Wait some time for the network changes to propagate. Can't use
        // waitUntil(isAirplaneModeOn() == on) because the response quickly gives the new
        // airplane mode status even though the network changes haven't propagated all the way to
        // JobScheduler.
        Thread.sleep(5000);
    }

    /**
     * Ensures that restrict background data usage policy is turned off.
     * If the policy is on, it interferes with tests that relies on metered connection.
     */
    void setDataSaverEnabled(boolean enabled) throws Exception {
        SystemUtil.runShellCommand(mInstrumentation,
                enabled ? RESTRICT_BACKGROUND_ON_CMD : RESTRICT_BACKGROUND_OFF_CMD);
    }

    private void setLocationMode(String mode) throws Exception {
        Settings.Secure.putString(mContext.getContentResolver(),
                Settings.Secure.LOCATION_MODE, mode);
        final LocationManager locationManager = mContext.getSystemService(LocationManager.class);
        final boolean wantEnabled = !String.valueOf(Settings.Secure.LOCATION_MODE_OFF).equals(mode);
        waitUntil("Location " + (wantEnabled ? "not enabled" : "still enabled"),
                () -> wantEnabled == locationManager.isLocationEnabled());
    }

    void setWifiMeteredState(boolean metered) throws Exception {
        if (metered) {
            // Make sure unmetered cellular networks don't interfere.
            setAirplaneMode(true);
            setWifiState(true);
        }
        final String ssid = getWifiSSID();
        setWifiMeteredState(ssid, metered ? "true" : "false");
    }

    // metered should be "true", "false" or "none"
    private void setWifiMeteredState(String ssid, String metered) {
        if (metered.equals(getWifiMeteredStatus(ssid))) {
            return;
        }
        SystemUtil.runShellCommand("cmd netpolicy set metered-network " + ssid + " " + metered);
        assertEquals(getWifiMeteredStatus(ssid), metered);
    }

    /**
     * Set Wifi connection to specific state, and block until we've verified
     * that we are in the state.
     * Taken from {@link android.net.http.cts.ApacheHttpClientTest}.
     */
    void setWifiState(final boolean enable) throws Exception {
        if (enable != isWiFiConnected()) {
            NetworkRequest nr = new NetworkRequest.Builder().clearCapabilities().build();
            NetworkCapabilities nc = new NetworkCapabilities.Builder()
                    .addTransportType(TRANSPORT_WIFI)
                    .build();
            NetworkTracker tracker = new NetworkTracker(nc, enable, mConnectivityManager);
            mConnectivityManager.registerNetworkCallback(nr, tracker);

            if (enable) {
                SystemUtil.runShellCommand("svc wifi enable");
                waitUntil("Failed to enable Wifi", 30 /* seconds */,
                        this::isWifiEnabled);
                //noinspection deprecation
                SystemUtil.runWithShellPermissionIdentity(mWifiManager::reconnect,
                        android.Manifest.permission.NETWORK_SETTINGS);
            } else {
                SystemUtil.runShellCommand("svc wifi disable");
            }

            tracker.waitForStateChange();

            assertEquals("Wifi must be " + (enable ? "connected to" : "disconnected from")
                    + " an access point for this test.", enable, isWiFiConnected());

            mConnectivityManager.unregisterNetworkCallback(tracker);
        }
    }

    void tearDown() throws Exception {
        // Restore initial restrict background data usage policy
        setDataSaverEnabled(mInitialDataSaverState);

        // Ensure that we leave WiFi in its previous state.
        if (mHasWifi) {
            if (mInitialWiFiSSID != null) {
                setWifiMeteredState(mInitialWiFiSSID, mInitialWiFiMeteredState);
            }
            if (mWifiManager.isWifiEnabled() != mInitialWiFiState) {
                try {
                    setWifiState(mInitialWiFiState);
                } catch (AssertionFailedError e) {
                    // Don't fail the test just because wifi state wasn't set in tearDown.
                    Log.e(TAG, "Failed to return wifi state to " + mInitialWiFiState, e);
                }
            }
        }

        // Restore initial airplane mode status. Do it after setting wifi in case wifi was
        // originally metered.
        if (isAirplaneModeOn() != mInitialAirplaneModeState) {
            setAirplaneMode(mInitialAirplaneModeState);
        }

        setLocationMode(mInitialLocationMode);
    }

    private String unquoteSSID(String ssid) {
        // SSID is returned surrounded by quotes if it can be decoded as UTF-8.
        // Otherwise it's guaranteed not to start with a quote.
        if (ssid.charAt(0) == '"') {
            return ssid.substring(1, ssid.length() - 1);
        } else {
            return ssid;
        }
    }

    static class NetworkTracker extends ConnectivityManager.NetworkCallback {
        private static final int MSG_CHECK_ACTIVE_NETWORK = 1;
        private final ConnectivityManager mConnectivityManager;

        private final CountDownLatch mReceiveLatch = new CountDownLatch(1);

        private final NetworkCapabilities mExpectedCapabilities;

        private final boolean mExpectedConnected;

        private final Handler mHandler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(Message msg) {
                if (msg.what == MSG_CHECK_ACTIVE_NETWORK) {
                    checkActiveNetwork();
                }
            }
        };

        NetworkTracker(NetworkCapabilities expectedCapabilities, boolean expectedConnected,
                ConnectivityManager cm) {
            mExpectedCapabilities = expectedCapabilities;
            mExpectedConnected = expectedConnected;
            mConnectivityManager = cm;
        }

        @Override
        public void onAvailable(Network network) {
            // Available doesn't mean it's the active network. We need to check that separately.
            checkActiveNetwork();
        }

        @Override
        public void onLost(Network network) {
            checkActiveNetwork();
        }

        boolean waitForStateChange() throws InterruptedException {
            checkActiveNetwork();
            return mReceiveLatch.await(60, TimeUnit.SECONDS);
        }

        private void checkActiveNetwork() {
            mHandler.removeMessages(MSG_CHECK_ACTIVE_NETWORK);
            if (mReceiveLatch.getCount() == 0) {
                return;
            }

            Network activeNetwork = mConnectivityManager.getActiveNetwork();
            if (mExpectedConnected) {
                if (activeNetwork != null && mExpectedCapabilities.satisfiedByNetworkCapabilities(
                        mConnectivityManager.getNetworkCapabilities(activeNetwork))) {
                    mReceiveLatch.countDown();
                } else {
                    mHandler.sendEmptyMessageDelayed(MSG_CHECK_ACTIVE_NETWORK, 5000);
                }
            } else {
                if (activeNetwork == null
                        || !mExpectedCapabilities.satisfiedByNetworkCapabilities(
                        mConnectivityManager.getNetworkCapabilities(activeNetwork))) {
                    mReceiveLatch.countDown();
                } else {
                    mHandler.sendEmptyMessageDelayed(MSG_CHECK_ACTIVE_NETWORK, 5000);
                }
            }
        }
    }
}
