# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import logging

from autotest_lib.client.common_lib import error
from autotest_lib.client.cros.enterprise import enterprise_policy_base
from autotest_lib.client.cros.enterprise import enterprise_network_api


class policy_WiFiAutoconnect(
        enterprise_policy_base.EnterprisePolicyTest):
    version = 1


    def cleanup(self):
        """Re-enable ethernet after the test is completed."""
        self.net_api.chrome_net_context.enable_network_device('Ethernet')
        super(policy_WiFiAutoconnect, self).cleanup()


    def test_wifi_autoconnect(self, ssid, autoconnect):
        """
        Verifies the behavior of the autoconnect portion of network policy.

        @param ssid: Service set identifier for wireless local area network.
        @param autoconnect: Whether policy autoconnects to network.

        @raises error.TestFail: When device's behavior does not match policy.

        """
        if not autoconnect:
            if self.net_api.is_network_connected(ssid):
                raise error.TestFail('Device autoconnected to %s, but '
                                     'autoconnect = False.'
                                     % ssid)
            self.net_api.connect_to_network(ssid)

        if not self.net_api.is_network_connected(ssid):
            raise error.TestFail('Did not connect to network (%s)' % ssid)


    def run_once(self, autoconnect=False, ssid=''):
        """
        Setup and run the test configured for the specified test case.

        @param ssid: Service set identifier for wireless local area network.
        @param autoconnect: Value of "AutoConnect" setting. Options are True,
                            False, or None

        """
        net_policy = enterprise_network_api.\
                         create_network_policy(ssid, autoconnect)

        self.setup_case(
            user_policies={
                'OpenNetworkConfiguration': net_policy
            },
            extension_paths=[enterprise_network_api.NETWORK_TEST_EXTENSION_PATH]
        )

        self.net_api = enterprise_network_api.\
                ChromeEnterpriseNetworkContext(self.cr)
        # Disable ethernet so device will default to WiFi
        self.net_api.disable_network_device('Ethernet')

        self.test_wifi_autoconnect(ssid, autoconnect)
