#
#   Copyright 2019 - 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.

import time

from acts import asserts
from acts.controllers.openwrt_ap import MOBLY_CONTROLLER_CONFIG_NAME as OPENWRT
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.net import connectivity_const as cconst
from acts_contrib.test_utils.net import connectivity_test_utils as cutils
from acts_contrib.test_utils.net import ui_utils as uutils
from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest

WifiEnums = wutils.WifiEnums
IFACE = "InterfaceName"
TIME_OUT = 20
WLAN = "wlan0"
ACCEPT_CONTINUE = "Accept and Continue"
CONNECTED = "Connected"
SIGN_IN_NOTIFICATION = "Sign in to network"
FAS_FDQN = "netsplashpage.net"


class CaptivePortalTest(WifiBaseTest):
    """Check device can access the network after pass captive portal check."""

    def setup_class(self):
        """Setup devices for tests and unpack params.

        Required params:
          1. rk_captive_portal: SSID of ruckus captive portal network in dict
          2. gg_captive_portal: SSID of guestgate network in dict
          3. uicd_workflows: uicd workflow that specify click actions to accept
             a captive portal connection. Ex: Click on SignIn, Accept & Continue
             //wireless/android/platform/testing/wifi/configs/uicd/
          4. uic_zip: Zip file location of UICD application
        """
        self.dut = self.android_devices[0]
        opt_params = ["rk_captive_portal", "gg_captive_portal",
                      "configure_OpenWrt", "wifi_network"]
        self.unpack_userparams(opt_param_names=opt_params,)
        wutils.wifi_test_device_init(self.dut)

        if OPENWRT in self.user_params:
            self.openwrt = self.access_points[0]
            if hasattr(self, "configure_OpenWrt") and self.configure_OpenWrt == "skip":
                self.dut.log.info("Skip configure Wifi interface due to config setup.")
            else:
                self.configure_openwrt_ap_and_start(wpa_network=True)
                self.wifi_network = self.openwrt.get_wifi_network()
            self.openwrt.network_setting.setup_captive_portal(FAS_FDQN)

    def teardown_class(self):
        """Reset devices."""
        cutils.set_private_dns(self.dut, cconst.PRIVATE_DNS_MODE_OPPORTUNISTIC)
        wutils.reset_wifi(self.dut)
        self.dut.droid.telephonyToggleDataConnection(True)

    def setup_test(self):
        """Setup device."""
        wutils.reset_wifi(self.dut)
        self.dut.unlock_screen()
        self._go_to_wifi_settings()

    def on_fail(self, test_name, begin_time):
        self.dut.take_bug_report(test_name, begin_time)

    ### Helper methods ###

    def _go_to_wifi_settings(self):
        """Go to wifi settings to perform UI actions for Captive portal."""
        self.dut.adb.shell("am start -a android.settings.SETTINGS")
        asserts.assert_true(
            uutils.has_element(self.dut, text="Network & internet"),
            "Failed to find 'Network & internet' icon")
        uutils.wait_and_click(self.dut, text="Network & internet")
        android_version = self.dut.adb.getprop("ro.build.version.release")
        if int(android_version) < 12:
            uutils.wait_and_click(self.dut, text="Wi‑Fi")
        else:
            uutils.wait_and_click(self.dut, text="Internet")

    def _verify_sign_in_notification(self):
        """Verify sign in notification shows for captive portal."""
        curr_time = time.time()
        while time.time() < curr_time + TIME_OUT:
            time.sleep(3) # wait for sometime before checking the notification
            screen_dump = uutils.get_screen_dump_xml(self.dut)
            nodes = screen_dump.getElementsByTagName('node')
            for node in nodes:
                if SIGN_IN_NOTIFICATION in node.getAttribute(
                    'text') or CONNECTED in node.getAttribute('text'):
                  return
        asserts.fail("Failed to get sign in notification")

    def _verify_captive_portal(self, network, user="username",
                               mail="user@example.net",
                               click_accept=ACCEPT_CONTINUE):
        """Connect to captive portal network using uicd workflow.

        Steps:
            1. Connect to captive portal network
            2. Run uicd workflow to accept connection
            3. Verify internet connectivity

        Args:
            network: captive portal network to connect to
            user: Option for captive portal login in
            mail: Option for captive portal login in
            click_accept: Notification to select to accept captive portal
        """
        # connect to captive portal wifi network
        wutils.connect_to_wifi_network(
            self.dut, network, check_connectivity=False)
        # Wait for captive portal detection.
        time.sleep(10)
        # run ui automator
        self._verify_sign_in_notification()
        uutils.wait_and_click(self.dut, text="%s" % network["SSID"])
        if uutils.has_element(self.dut, class_name="android.widget.EditText"):
            uutils.wait_and_click(self.dut, class_name="android.widget.EditText")
            self.dut.adb.shell("input text %s" % user)
            self.dut.adb.shell("input keyevent 20")
            self.dut.adb.shell("input text %s" % mail)
            uutils.wait_and_click(self.dut, text="Accept Terms of Service")
        if uutils.has_element(self.dut, text="%s" % click_accept):
            uutils.wait_and_click(self.dut, text="%s" % click_accept)

        # wait for sometime for captive portal connection to go through
        curr_time = time.time()
        while time.time() < curr_time + TIME_OUT:
            time.sleep(3) # wait for sometime for AP to send DHCP info
            link_prop = self.dut.droid.connectivityGetActiveLinkProperties()
            self.log.debug("Link properties %s" % link_prop)
            if link_prop and link_prop[IFACE] == WLAN:
                break

        # verify connectivity
        asserts.assert_true(
            wutils.validate_connection(self.dut, ping_gateway=False),
            "Failed to connect to internet. Captive portal test failed")

    ### Test Cases ###

    @test_tracker_info(uuid="b035b4f9-40f7-42f6-9941-ec27afe15040")
    @WifiBaseTest.wifi_test_wrap
    def test_ruckus_captive_portal_default(self):
        """Verify captive portal network.

        Steps:
            1. Set default private dns mode
            2. Connect to ruckus captive portal network
            3. Verify connectivity
        """
        # set private dns to opportunistic
        cutils.set_private_dns(self.dut, cconst.PRIVATE_DNS_MODE_OPPORTUNISTIC)

        # verify connection to captive portal network
        self._verify_captive_portal(self.rk_captive_portal)

    @test_tracker_info(uuid="8ea18d80-0170-41b1-8945-fe14bcd4feab")
    @WifiBaseTest.wifi_test_wrap
    def test_ruckus_captive_portal_private_dns_off(self):
        """Verify captive portal network.

        Steps:
            1. Turn off private dns mode
            2. Connect to ruckus captive portal network
            3. Verify connectivity
        """
        # turn off private dns
        cutils.set_private_dns(self.dut, cconst.PRIVATE_DNS_MODE_OFF)

        # verify connection to captive portal network
        self._verify_captive_portal(self.rk_captive_portal)

    @test_tracker_info(uuid="e8e05907-55f7-40e5-850c-b3111ceb31a4")
    @WifiBaseTest.wifi_test_wrap
    def test_ruckus_captive_portal_private_dns_strict(self):
        """Verify captive portal network.

        Steps:
            1. Set strict private dns mode
            2. Connect to ruckus captive portal network
            3. Verify connectivity
        """
        # set private dns to strict mode
        cutils.set_private_dns(self.dut,
                               cconst.PRIVATE_DNS_MODE_STRICT,
                               cconst.DNS_GOOGLE_HOSTNAME)

        # verify connection to captive portal network
        self._verify_captive_portal(self.rk_captive_portal)

    @test_tracker_info(uuid="76e49800-f141-4fd2-9969-562585eb1e7a")
    def test_guestgate_captive_portal_default(self):
        """Verify captive portal network.

        Steps:
            1. Set default private dns mode
            2. Connect to guestgate captive portal network
            3. Verify connectivity
        """
        # set private dns to opportunistic
        cutils.set_private_dns(self.dut, cconst.PRIVATE_DNS_MODE_OPPORTUNISTIC)

        # verify connection to captive portal network
        self._verify_captive_portal(self.gg_captive_portal)

    @test_tracker_info(uuid="0aea0cac-0f42-406b-84ba-62c1ef74adfc")
    def test_guestgate_captive_portal_private_dns_off(self):
        """Verify captive portal network.

        Steps:
            1. Turn off private dns mode
            2. Connect to guestgate captive portal network
            3. Verify connectivity
        """
        # turn off private dns
        cutils.set_private_dns(self.dut, cconst.PRIVATE_DNS_MODE_OFF)

        # verify connection to captive portal network
        self._verify_captive_portal(self.gg_captive_portal)

    @test_tracker_info(uuid="39124dcc-2fd3-4d33-b129-a1c8150b7f2a")
    def test_guestgate_captive_portal_private_dns_strict(self):
        """Verify captive portal network.

        Steps:
            1. Set strict private dns mode
            2. Connect to guestgate captive portal network
            3. Verify connectivity
        """
        # set private dns to strict mode
        cutils.set_private_dns(self.dut,
                               cconst.PRIVATE_DNS_MODE_STRICT,
                               cconst.DNS_GOOGLE_HOSTNAME)

        # verify connection to captive portal network
        self._verify_captive_portal(self.gg_captive_portal)

    @test_tracker_info(uuid="c25a1be7-f202-41c4-ac95-bed1720833ab")
    def test_openwrt_captive_portal_default(self):
        """Verify captive portal network.

        Steps:
            1. Set default private dns mode
            2. Connect to openwrt captive portal network
            3. Verify connectivity
        """
        cutils.set_private_dns(self.dut, cconst.PRIVATE_DNS_MODE_OPPORTUNISTIC)
        self.openwrt.network_setting.service_manager.restart("opennds")
        self._verify_captive_portal(self.wifi_network, click_accept="Continue")

    @test_tracker_info(uuid="1419e36d-0303-44ba-bc60-4d707b45ef48")
    def test_openwrt_captive_portal_private_dns_off(self):
        """Verify captive portal network.

        Steps:
            1. Turn off private dns mode
            2. Connect to openwrt captive portal network
            3. Verify connectivity
        """
        cutils.set_private_dns(self.dut, cconst.PRIVATE_DNS_MODE_OFF)
        self.openwrt.network_setting.service_manager.restart("opennds")
        self._verify_captive_portal(self.wifi_network, click_accept="Continue")

    @test_tracker_info(uuid="5aae44ee-fa62-47b9-9b3d-8121f9f92da1")
    def test_openwrt_captive_portal_private_dns_strict(self):
        """Verify captive portal network.

        Steps:
            1. Set strict private dns mode
            2. Connect to openwrt captive portal network
            3. Verify connectivity
        """
        cutils.set_private_dns(self.dut,
                               cconst.PRIVATE_DNS_MODE_STRICT,
                               cconst.DNS_GOOGLE_HOSTNAME)
        self.openwrt.network_setting.service_manager.restart("opennds")
        self._verify_captive_portal(self.wifi_network, click_accept="Continue")


