# Copyright (c) 2013 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.

from autotest_lib.client.common_lib import error
from autotest_lib.client.cros import dhcp_handling_rule
from autotest_lib.client.cros import dhcp_packet
from autotest_lib.client.cros import dhcp_test_base
from autotest_lib.client.cros import shill_temporary_profile

# This hacks the path so that we can import shill_proxy.
# pylint: disable=W0611
from autotest_lib.client.cros import flimflam_test_path
# pylint: enable=W0611
import shill_proxy

class network_DhcpStaticIP(dhcp_test_base.DhcpTestBase):
    """DHCP test which confirms static IP functionality"""
    # Length of time the lease from the DHCP server is valid.
    LEASE_TIME_SECONDS = 60
    # We'll fill in the subnet and give this address to the client over DHCP.
    INTENDED_IP_SUFFIX = '0.0.0.101'
    # We'll fill in the subnet and supply this as a static IP address.
    STATIC_IP_SUFFIX = '0.0.0.201'
    STATIC_IP_NAME_SERVERS = [ '1.1.2.2', '1.1.3.4' ]
    # Time to wait for the DHCP negotiation protocol to complete.
    DHCP_NEGOTIATION_TIMEOUT_SECONDS = 10
    # Time to wait after DHCP negotiation completes until service is marked
    # as connected.
    DHCP_SETUP_TIMEOUT_SECONDS = 3
    # Name given to the temporary shill profile we create for this test.
    TEST_PROFILE_NAME = 'TestStaticIP'
    # Various parameters that can be set statically.
    CONFIGURE_STATIC_IP_ADDRESS = 'ip-address'
    CONFIGURE_STATIC_IP_DNS_SERVERS = 'dns-servers'

    def get_device(self, interface_name):
        """Finds the corresponding Device object for an interface with
        the name |interface_name|.

        @param interface_name string The name of the interface to check.

        @return DBus interface object representing the associated device.

        """
        device = self._shill_proxy.find_object('Device',
                                               {'Name': interface_name})
        if device is None:
            raise error.TestFail('Device was not found.')

        return device


    def find_ethernet_service(self, interface_name):
        """Finds the corresponding service object for an ethernet
        interface.

        @param interface_name string The name of the associated interface

        @return Service object representing the associated service.

        """
        device = self.get_device(interface_name)
        device_path = shill_proxy.ShillProxy.dbus2primitive(device.object_path)
        return self._shill_proxy.find_object('Service', {'Device': device_path})


    def configure_static_ip(self, service, params):
        """Configures the Static IP parameters for the Ethernet interface
        |interface_name| and applies those parameters to the interface by
        forcing a re-connect.

        @param service object the Service DBus interface to configure.
        @param params list of static parameters to set on the service.

        """

        self._static_ip_options = {}
        if self.CONFIGURE_STATIC_IP_ADDRESS in params:
            subnet_mask = self.ethernet_pair.interface_subnet_mask
            static_ip_address = dhcp_test_base.DhcpTestBase.rewrite_ip_suffix(
                    subnet_mask,
                    self.server_ip,
                    self.STATIC_IP_SUFFIX)
            prefix_len = self.ethernet_pair.interface_prefix
            service.SetProperty('StaticIP.Address', static_ip_address)
            service.SetProperty('StaticIP.Prefixlen', prefix_len)
            self._static_ip_options[dhcp_packet.OPTION_REQUESTED_IP] = (
                    static_ip_address)
        if self.CONFIGURE_STATIC_IP_DNS_SERVERS in params:
            service.SetProperty('StaticIP.NameServers',
                                ','.join(self.STATIC_IP_NAME_SERVERS))
            self._static_ip_options[dhcp_packet.OPTION_DNS_SERVERS] = (
                    self.STATIC_IP_NAME_SERVERS)
        service.Disconnect()
        service.Connect()


    def clear_static_ip(self, service, params):
        """Clears configuration of Static IP parameters for the Ethernet
        interface and forces a re-connect.

        @param service object the Service DBus interface to clear properties.
        @param params list of static parameters to clear from the service.

        """
        if self.CONFIGURE_STATIC_IP_ADDRESS in params:
            service.ClearProperty('StaticIP.Address')
            service.ClearProperty('StaticIP.Prefixlen')
        if self.CONFIGURE_STATIC_IP_DNS_SERVERS in params:
            service.ClearProperty('StaticIP.NameServers')
        service.Disconnect()
        service.Connect()


    def check_saved_ip(self, service, options):
        """Check the properties of the Ethernet service to make sure that
        the address provided by the DHCP server is properly added to the
        "Saved.Address".

        @param service object the Service DBus interface to clear properties.
        @param options dict parameters that were used to configure the DHCP
            server.

        """
        intended_ip = options[dhcp_packet.OPTION_REQUESTED_IP]
        properties = service.GetProperties()
        if intended_ip != properties['SavedIP.Address']:
            raise error.TestFail('Saved IP address %s is not DHCP address %s' %
                                 (properties['SavedIP.Address'], intended_ip))


    def make_lease_negotiation_rules(self, options):
        """Generate a set of lease negotiation handling rules for a
        server that will successfully return an IP address to the client.

        @param options dict of options to be negotiated.  In particular,
            the dhcp_packet.OPTION_REQUESTED_IP element is used to configure
            the address that will be returned to the client.
        @return array of DhcpHandlingRule instances which implement the
            negotiation.

        """
        intended_ip = options[dhcp_packet.OPTION_REQUESTED_IP]
        rules = []
        rules.append(dhcp_handling_rule.DhcpHandlingRule_RespondToDiscovery(
                intended_ip,
                self.server_ip,
                options,
                {}))
        rules.append(dhcp_handling_rule.DhcpHandlingRule_RespondToRequest(
                intended_ip,
                self.server_ip,
                options,
                {}))
        return rules


    def test_dhcp_negotiation(self, rules, service):
        """Perform a DHCP lease negotiation using handler rules from |rules|,
        and ensure that |service| becomes connected as a result.

        @param rules array of handling rules that must complete in order for
            the negotiation to be considered successful.
        @param service Service DBus object which should become connected as
            a result of the DHCP negotiation.

        """
        rules[-1].is_final_handler = True
        self.server.start_test(rules, self.DHCP_NEGOTIATION_TIMEOUT_SECONDS)
        self.server.wait_for_test_to_finish()
        if not self.server.last_test_passed:
            raise error.TestFail('Test server didn\'t get all the messages it '
                                 'was told to expect during negotiation.')
        # Wait for the service to enter a "good" state.
        connect_result = self._shill_proxy.wait_for_property_in(
                service,
                self._shill_proxy.SERVICE_PROPERTY_STATE,
                ('ready', 'portal', 'online'),
                self.DHCP_SETUP_TIMEOUT_SECONDS)
        (successful, _, association_time) = connect_result
        if not successful:
            raise error.TestFail('Ethernet service did not become connected.')


    def connect_dynamic_ip(self, options, service):
        """Perform a DHCP negotiation, using |options|.  Then check that
           the IP information configured on client matches the parameters
           in |options|.

        @param options dict containing DHCP packet options to be returned
            to the client during negotiation, and then later checked for
            consistency.
        @param service DBus object of the service that should become
            connected as a result of the negotiation.

        """
        self.test_dhcp_negotiation(self.make_lease_negotiation_rules(options),
                                   service)
        self.check_dhcp_config(options)


    def connect_static_ip(self, options, service, params):
        """Perform a DHCP negotiation, using |options|.  Then check that
           the IP information configured on client matches the parameters
           in |options|, except that the client's IP address should be
           |static_ip_address|.

        @param options dict containing DHCP packet options to be returned
            to the client during negotiation, and then later checked for
            consistency.
        @param service DBus object of the service that should become
            connected as a result of the negotiation.
        @param params list of static IP parameters we will be verifying.

        """
        rules = self.make_lease_negotiation_rules(options)
        if self.CONFIGURE_STATIC_IP_ADDRESS in params:
            # Add a rule that expects the client to release the lease.
            rules.append(dhcp_handling_rule.DhcpHandlingRule_AcceptRelease(
                    self.server_ip,
                    options,
                    {}))
        self.test_dhcp_negotiation(rules, service)

        # Check to make sure that the configured IP address of the client
        # matches the configured static IP address.
        static_ip_options = options.copy()
        static_ip_options.update(self._static_ip_options)
        self.check_dhcp_config(static_ip_options)
        self.check_saved_ip(service, options)


    def test_body(self):
        """The test main body"""
        subnet_mask = self.ethernet_pair.interface_subnet_mask
        intended_ip = dhcp_test_base.DhcpTestBase.rewrite_ip_suffix(
                subnet_mask,
                self.server_ip,
                self.INTENDED_IP_SUFFIX)
        # Two real name servers, and a bogus one to be unpredictable.
        dns_servers = ['8.8.8.8', '8.8.4.4', '192.168.87.88']
        domain_name = 'corp.google.com'
        dns_search_list = [
                'corgie.google.com',
                'lies.google.com',
                'that.is.a.tasty.burger.google.com',
                ]
        # This is the pool of information the server will give out to the client
        # upon request.
        dhcp_options = {
                dhcp_packet.OPTION_SERVER_ID : self.server_ip,
                dhcp_packet.OPTION_SUBNET_MASK : subnet_mask,
                dhcp_packet.OPTION_IP_LEASE_TIME : self.LEASE_TIME_SECONDS,
                dhcp_packet.OPTION_REQUESTED_IP : intended_ip,
                dhcp_packet.OPTION_DNS_SERVERS : dns_servers,
                dhcp_packet.OPTION_DOMAIN_NAME : domain_name,
                dhcp_packet.OPTION_DNS_DOMAIN_SEARCH_LIST : dns_search_list,
                }
        self._shill_proxy = shill_proxy.ShillProxy()
        service = self.find_ethernet_service(
                self.ethernet_pair.peer_interface_name)

        manager = self._shill_proxy.manager
        with shill_temporary_profile.ShillTemporaryProfile(
                manager, profile_name=self.TEST_PROFILE_NAME):

            self.connect_dynamic_ip(dhcp_options, service)

            for params in self._static_param_list:
                self.configure_static_ip(service, params)
                self.connect_static_ip(dhcp_options, service, params)
                self.clear_static_ip(service, params)

            self.connect_dynamic_ip(dhcp_options, service)


    def run_once(self, static_param_list):
        """Setup the static parameter list before calling the DhcpTestBase
        main loop.

        @param static_param_list list of iterable properties to configure
            for each static IP test.

        """
        self._static_param_list = static_param_list
        super(network_DhcpStaticIP, self).run_once()
