# Lint as: python2, python3
# Copyright 2015 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.

"""
Base class for DHCPv6 tests.  This class just sets up a little bit of plumbing,
like a virtual ethernet device with one end that looks like a real ethernet
device to shill and a DHCPv6 test server on the end that doesn't look like a
real ethernet interface to shill.  Child classes should override test_body()
with the logic of their test.
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import logging
import six
from six.moves import filter
from six.moves import range
import time
import traceback

from autotest_lib.client.bin import test
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros import virtual_ethernet_pair
from autotest_lib.client.cros import dhcpv6_test_server
from autotest_lib.client.cros.networking import shill_proxy

# These are keys that may be used with the DBus dictionary returned from
# Dhcpv6TestBase.get_interface_ipconfig().
DHCPV6_KEY_ADDRESS = 'Address'
DHCPV6_KEY_DELEGATED_PREFIX = 'DelegatedPrefix'
DHCPV6_KEY_DELEGATED_PREFIX_LENGTH = 'DelegatedPrefixLength'
DHCPV6_KEY_NAMESERVERS = 'NameServers'
DHCPV6_KEY_SEARCH_DOMAIN_LIST = 'SearchDomains'

# After DHCPv6 completes, an ipconfig should appear shortly after
IPCONFIG_POLL_COUNT = 5
IPCONFIG_POLL_PERIOD_SECONDS = 1

class Dhcpv6TestBase(test.test):
    """Parent class for tests that work verify DHCPv6 behavior."""
    version = 1

    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.

        """
        return self.shill_proxy.find_object('Device',
                                            {'Name': interface_name})


    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 get_interface_ipconfig_objects(self, interface_name):
        """
        Returns a list of dbus object proxies for |interface_name|.
        Returns an empty list if no such interface exists.

        @param interface_name string name of the device to query (e.g., "eth0").

        @return list of objects representing DBus IPConfig RPC endpoints.

        """
        device = self.get_device(interface_name)
        if device is None:
            return []

        if six.PY2:
            device_properties = device.GetProperties(utf8_strings=True)
        else:
            device_properties = device.GetProperties()
        proxy = self.shill_proxy

        ipconfig_object = proxy.DBUS_TYPE_IPCONFIG
        return list(filter(bool,
                      [ proxy.get_dbus_object(ipconfig_object, property_path)
                        for property_path in device_properties['IPConfigs'] ]))


    def get_interface_ipconfig(self, interface_name):
        """
        Returns a dictionary containing settings for an |interface_name| set
        via DHCPv6.  Returns None if no such interface or setting bundle on
        that interface can be found in shill.

        @param interface_name string name of the device to query (e.g., "eth0").

        @return dict containing the the properties of the IPConfig stripped
            of DBus meta-data or None.

        """
        dhcp_properties = None
        for ipconfig in self.get_interface_ipconfig_objects(interface_name):
            logging.info('Looking at ipconfig %r', ipconfig)
            if six.PY2:
                ipconfig_properties = ipconfig.GetProperties(utf8_strings=True)
            else:
                ipconfig_properties = ipconfig.GetProperties()
            if 'Method' not in ipconfig_properties:
                logging.info('Found ipconfig object with no method field')
                continue
            if ipconfig_properties['Method'] != 'dhcp6':
                logging.info('Found ipconfig object with method != dhcp6')
                continue
            if dhcp_properties != None:
                raise error.TestFail('Found multiple ipconfig objects '
                                     'with method == dhcp6')
            dhcp_properties = ipconfig_properties
        if dhcp_properties is None:
            logging.info('Did not find IPConfig object with method == dhcp6')
            return None
        logging.info('Got raw dhcp config dbus object: %s.', dhcp_properties)
        return shill_proxy.ShillProxy.dbus2primitive(dhcp_properties)


    def run_once(self):
        self._server = None
        self._server_ip = None
        self._ethernet_pair = None
        self._shill_proxy = shill_proxy.ShillProxy()
        try:
            # TODO(zqiu): enable DHCPv6 for peer interface, either by restarting
            # shill with appropriate command line options or via a new DBUS
            # command.
            self._ethernet_pair = virtual_ethernet_pair.VirtualEthernetPair(
                    interface_ip=None,
                    peer_interface_name='pseudoethernet0',
                    peer_interface_ip=None,
                    interface_ipv6=dhcpv6_test_server.DHCPV6_SERVER_ADDRESS)
            self._ethernet_pair.setup()
            if not self._ethernet_pair.is_healthy:
                raise error.TestFail('Could not create virtual ethernet pair.')
            self._server_ip = self._ethernet_pair.interface_ip
            self._server = dhcpv6_test_server.Dhcpv6TestServer(
                    self._ethernet_pair.interface_name)
            self._server.start()
            self.test_body()
        except (error.TestFail, error.TestNAError):
            # Pass these through without modification.
            raise
        except Exception as e:
            logging.error('Caught exception: %s.', str(e))
            logging.error('Trace: %s', traceback.format_exc())
            raise error.TestFail('Caught exception: %s.' % str(e))
        finally:
            if self._server is not None:
                self._server.stop()
            if self._ethernet_pair is not None:
                self._ethernet_pair.teardown()

    def test_body(self):
        """
        Override this method with the body of your test.  You may safely assume
        that the the properties exposed by DhcpTestBase correctly return
        references to the test apparatus.
        """
        raise error.TestFail('No test body implemented')

    @property
    def server_ip(self):
        """
        Return the IP address of the side of the interface that the DHCPv6 test
        server is bound to.  The server itself is bound the the broadcast
        address on the interface.
        """
        return self._server_ip

    @property
    def server(self):
        """
        Returns a reference to the DHCP test server.  Use this to add handlers
        and run tests.
        """
        return self._server

    @property
    def ethernet_pair(self):
        """
        Returns a reference to the virtual ethernet pair created to run DHCP
        tests on.
        """
        return self._ethernet_pair

    @property
    def shill_proxy(self):
        """
        Returns a the shill proxy instance.
        """
        return self._shill_proxy


    def check_dhcpv6_config(self):
        """
        Compare the DHCPv6 ipconfig with DHCP lease parameters to ensure
        that the DUT attained the correct values.

        """
        # Retrieve DHCPv6 configuration.
        for attempt in range(IPCONFIG_POLL_COUNT):
            dhcpv6_config = self.get_interface_ipconfig(
                    self.ethernet_pair.peer_interface_name)
            # Wait until both IP address and delegated prefix are obtained.
            if (dhcpv6_config is not None and
                dhcpv6_config.get(DHCPV6_KEY_ADDRESS) and
                dhcpv6_config.get(DHCPV6_KEY_DELEGATED_PREFIX)):
                break;
            time.sleep(IPCONFIG_POLL_PERIOD_SECONDS)
        else:
            raise error.TestFail('Failed to retrieve DHCPv6 ipconfig object '
                                 'from shill.')

        # Verify Non-temporary Address prefix.
        address = dhcpv6_config.get(DHCPV6_KEY_ADDRESS)
        actual_prefix = address[:address.index('::')]
        expected_prefix = dhcpv6_test_server.DHCPV6_SERVER_SUBNET_PREFIX[:
                dhcpv6_test_server.DHCPV6_SERVER_SUBNET_PREFIX.index('::')]
        if actual_prefix != expected_prefix:
            raise error.TestFail('Address prefix mismatch: '
                                 'actual %s expected %s.' %
                                 (actual_prefix, expected_prefix))
        # Verify Non-temporary Address suffix.
        actual_suffix = int(address[address.index('::')+2:], 16)
        if (actual_suffix < dhcpv6_test_server.DHCPV6_ADDRESS_RANGE_LOW or
            actual_suffix > dhcpv6_test_server.DHCPV6_ADDRESS_RANGE_HIGH):
            raise error.TestFail('Invalid address suffix: '
                                 'actual %x expected (%x-%x)' %
                                 (actual_suffix,
                                  dhcpv6_test_server.DHCPV6_ADDRESS_RANGE_LOW,
                                  dhcpv6_test_server.DHCPV6_ADDRESS_RANGE_HIGH))

        # Verify delegated prefix.
        delegated_prefix = dhcpv6_config.get(DHCPV6_KEY_DELEGATED_PREFIX)
        for x in range(
                dhcpv6_test_server.DHCPV6_PREFIX_DELEGATION_INDEX_LOW,
                dhcpv6_test_server.DHCPV6_PREFIX_DELEGATION_INDEX_HIGH+1):
            valid_prefix = \
                    dhcpv6_test_server.DHCPV6_PREFIX_DELEGATION_RANGE_FORMAT % x
            if delegated_prefix == valid_prefix:
                break;
        else:
            raise error.TestFail('Invalid delegated prefix: %s' %
                                 (delegated_prefix))
        # Verify delegated prefix length.
        delegated_prefix_length = \
                int(dhcpv6_config.get(DHCPV6_KEY_DELEGATED_PREFIX_LENGTH))
        expected_delegated_prefix_length = \
                dhcpv6_test_server.DHCPV6_PREFIX_DELEGATION_PREFIX_LENGTH
        if delegated_prefix_length != expected_delegated_prefix_length:
            raise error.TestFail('Delegated prefix length mismatch: '
                                 'actual %d expected %d' %
                                 (delegated_prefix_length,
                                  expected_delegated_prefix_length))

        # Verify name servers.
        actual_name_servers = dhcpv6_config.get(DHCPV6_KEY_NAMESERVERS)
        expected_name_servers = \
                dhcpv6_test_server.DHCPV6_NAME_SERVERS.split(',')
        if actual_name_servers != expected_name_servers:
            raise error.TestFail('Name servers mismatch: actual %r expected %r'
                                 % (actual_name_servers, expected_name_servers))
        # Verify domain search.
        actual_domain_search = dhcpv6_config.get(DHCPV6_KEY_SEARCH_DOMAIN_LIST)
        expected_domain_search = \
                dhcpv6_test_server.DHCPV6_DOMAIN_SEARCH.split(',')
        if actual_domain_search != expected_domain_search:
            raise error.TestFail('Domain search list mismatch: '
                                 'actual %r expected %r' %
                                 (actual_domain_search, expected_domain_search))
