# Copyright 2014 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 dpkt
import logging
import time

from autotest_lib.client.bin import test
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros.tendo import peerd_config
from autotest_lib.client.cros import chrooted_avahi
from autotest_lib.client.cros.netprotos import interface_host
from autotest_lib.client.cros.netprotos import zeroconf
from autotest_lib.client.cros.tendo import peerd_dbus_helper


class peerd_HandlesNameConflicts(test.test):
    """Test that peerd can handle mDNS name conflicts."""
    version = 1

    CACHE_REFRESH_PERIOD_SECONDS = 5
    FAKE_HOST_HOSTNAME = 'a-test-host'
    TEST_TIMEOUT_SECONDS = 30
    TEST_SERVICE_ID = 'test-service-0'
    TEST_SERVICE_INFO = {'some_data': 'a value',
                          'other_data': 'another value'}
    INITIAL_MDNS_PREFIX = 'initial_mdns_prefix'
    SERBUS_SERVICE_ID = 'serbus'
    SERBUS_SERVICE_NAME = '_serbus'
    SERBUS_PROTOCOL = '_tcp'
    SERBUS_PORT = 0


    def reset_peerd(self):
        """Start up a peerd instance.

        This instance will have really verbose logging and will attempt
        to use a known MDNS prefix to start out.

        """
        self._peerd = peerd_dbus_helper.make_helper(
                peerd_config.PeerdConfig(verbosity_level=3,
                                         mdns_prefix=self.INITIAL_MDNS_PREFIX))


    def initialize(self):
        # Make sure these are initiallized to None in case we throw
        # during self.initialize().
        self._chrooted_avahi = None
        self._peerd = None
        self._host = None
        self._zc_listener = None
        self._chrooted_avahi = chrooted_avahi.ChrootedAvahi()
        self._chrooted_avahi.start()
        self.reset_peerd()
        # Listen on our half of the interface pair for mDNS advertisements.
        self._host = interface_host.InterfaceHost(
                self._chrooted_avahi.unchrooted_interface_name)
        self._zc_listener = zeroconf.ZeroconfDaemon(self._host,
                                                    self.FAKE_HOST_HOSTNAME)
        # The queries for hostname/dns_domain are IPCs and therefor relatively
        # expensive.  Do them just once.
        hostname = self._chrooted_avahi.hostname
        dns_domain = self._chrooted_avahi.dns_domain
        if not hostname or not dns_domain:
            raise error.TestFail('Failed to get hostname/domain from avahi.')
        self._dns_domain = dns_domain
        self._hostname = '%s.%s' % (hostname, dns_domain)
        self._last_cache_refresh_seconds = 0


    def cleanup(self):
        for obj in (self._chrooted_avahi,
                    self._host,
                    self._peerd):
            if obj is not None:
                obj.close()


    def _get_PTR_prefix(self, service_id):
        ptr_name = '_%s._tcp.%s' % (service_id, self._dns_domain)
        found_records = self._zc_listener.cached_results(
                ptr_name, dpkt.dns.DNS_PTR)
        if len(found_records) == 0:
            logging.debug('Found no PTR records for %s', ptr_name)
            return None
        if len(found_records) > 1:
            logging.debug('Found multiple PTR records for %s', ptr_name)
            return None
        unique_name = found_records[0].data
        expected_suffix = '.' + ptr_name
        if not unique_name.endswith(expected_suffix):
            logging.error('PTR record for "%s" points to odd name: "%s"',
                          ptr_name, unique_name)
            return None
        ptr_prefix = unique_name[0:-len(expected_suffix)]
        logging.debug('PTR record for "%s" points to service with name "%s"',
                      ptr_name, ptr_prefix)
        return ptr_prefix


    def _found_expected_PTR_records(self, forbidden_record_prefix):
        for service_id in (self.SERBUS_SERVICE_ID, self.TEST_SERVICE_ID):
            prefix = self._get_PTR_prefix(service_id)
            if prefix is None:
                break
            if prefix == forbidden_record_prefix:
                logging.debug('Ignoring service with conflicting prefix')
                break
        else:
            return True
        delta_seconds = time.time() - self._last_cache_refresh_seconds
        if delta_seconds > self.CACHE_REFRESH_PERIOD_SECONDS:
            self._zc_listener.clear_cache()
            self._last_cache_refresh_seconds = time.time()
        return False


    def run_once(self):
        # Tell peerd about this exciting new service we have.
        service_token = self._peerd.expose_service(self.TEST_SERVICE_ID,
                                                   self.TEST_SERVICE_INFO)
        # Wait for advertisements of that service to appear from avahi.
        # They should be prefixed with our special name, since there are no
        # conflicts.
        logging.info('Waiting to receive mDNS advertisements of '
                     'peerd services.')
        success, duration = self._host.run_until(
                lambda: self._found_expected_PTR_records(None),
                self.TEST_TIMEOUT_SECONDS)
        if not success:
            raise error.TestFail('Did not receive mDNS advertisements in time.')
        actual_prefix = self._get_PTR_prefix(self.SERBUS_SERVICE_ID)
        if actual_prefix != self.INITIAL_MDNS_PREFIX:
            raise error.TestFail('Expected initial mDNS advertisements to have '
                                 'a prefix=%s' % self.INITIAL_MDNS_PREFIX)
        logging.info('Found initial records advertised by peerd.')
        # Now register services with the same name, and restart peerd.
        # 1) The old instance of peerd should withdraw its services from Avahi
        # 2) The new instance of peerd should re-register services with Avahi
        # 3) Avahi should notice that the name.service_type.domain tuple
        #    conflicts with existing records, and signal this to peerd.
        # 4) Peerd should pick a new prefix and try again.
        self.reset_peerd()
        self._zc_listener.register_service(
                self.INITIAL_MDNS_PREFIX,
                self.SERBUS_SERVICE_NAME,
                self.SERBUS_PROTOCOL,
                self.SERBUS_PORT,
                ['invalid=record'])
        service_token = self._peerd.expose_service(self.TEST_SERVICE_ID,
                                                   self.TEST_SERVICE_INFO)
        run_until_predicate = lambda: self._found_expected_PTR_records(
                self.INITIAL_MDNS_PREFIX)
        success, duration = self._host.run_until(run_until_predicate,
                                                 self.TEST_TIMEOUT_SECONDS)
        if not success:
            raise error.TestFail('Timed out waiting for peerd to change the '
                                 'record prefix.')
