"""Global configuration of hosting checkers"""

from parallels.core import messages
from parallels.core.utils.common.ip import is_ipv4
from parallels.core.utils.config_utils import global_section
from parallels.core import MigrationError


class HostingCheckersConfig(object):
    """Hosting checkers global configurations

    Properties:

    'messages_delta_limit': The post-migration mail checks compare the number
    of messages in the source and the target mailboxes. If the number of
    messages differs more than it is specified in "messages_delta_limit", it is
    considered an error.

    'website_availability_check_timeout': Timeout on site response. When check
    the availability of site, limit response time. The default value is 30 seconds.
    
    'external_dns_servers': List of IP v4 addresses of external DNS servers
    that allows recursive DNS queries.  Hosting checks use the specified
    addresses to test whether general Internet users can obtain the correct DNS
    records for the transferred domains.

    'save_external_report_data_function': Function is used to store additional
    data that is too long for report.  It accepts two arguments - base name of
    a file, and file contents. It should store the contents to a file in some
    session directory and return path to the file (the returned path will be
    printed to report).     

    'dns_server_name': Name of target DNS server in report and log messages

    'panel_file_id': Name of a target panel in external data. Used to create
    names for files used by save_external_report_data_function function
    """
    def __init__(
        self, messages_delta_limit, website_availability_check_timeout,
        external_dns_servers, save_external_report_data_function,
        dns_server_name, panel_file_id, website_availability_depth=2,
        website_availability_group_directories=False
    ):
        """
        :type messages_delta_limit: int
        :type website_availability_check_timeout: int
        :type website_availability_depth: int
        :type website_availability_group_directories: bool
        """
        self.messages_delta_limit = messages_delta_limit
        self.website_availability_check_timeout = website_availability_check_timeout
        self.external_dns_servers = external_dns_servers
        self.save_external_report_data_function = save_external_report_data_function
        self.dns_server_name = dns_server_name
        self.panel_file_id = panel_file_id
        self.website_availability_depth = website_availability_depth
        self.website_availability_group_directories = website_availability_group_directories


class MigratorHostingCheckersConfig(HostingCheckersConfig):
    """Implementation of hosting checkers configuration used by migrator"""

    def __init__(self, config, save_external_report_data_function):
        self.config = config
        super(MigratorHostingCheckersConfig, self).__init__(
            messages_delta_limit=self._get_messages_delta_limit(),
            website_availability_check_timeout=self._get_website_availability_check_timeout(),
            external_dns_servers=self._get_external_dns_servers(),
            save_external_report_data_function=save_external_report_data_function,
            dns_server_name=messages.TARGET_DNS_SERVER_TITLE,
            panel_file_id='target',
            website_availability_depth=self._get_website_availability_depth(),
            website_availability_group_directories= self._get_website_availability_group_directories()
        )

    def _get_messages_delta_limit(self):
        """
        :rtype: int
        """
        return global_section(self.config).getint('mail-messages-delta-limit', 10)

    def _get_website_availability_check_timeout(self):
        """
        :rtype: int
        """
        return global_section(self.config).getint('website-availability-check-timeout', 30)

    def _get_website_availability_depth(self):
        """
        :rtype: int
        """
        return global_section(self.config).getint('website-availability-depth', 2)

    def _get_website_availability_group_directories(self):
        """
        :rtype: bool
        """
        return global_section(self.config).getboolean('website-availability-group-directories', False)

    def _get_external_dns_servers(self):
        external_dns_servers = []
        external_dns_server_ip = global_section(self.config).get(
            'external-dns-server', '8.8.8.8'
        )
        if external_dns_server_ip == 'none':
            # 'none' is a special value saying migrator to skip external DNS
            # tests
            pass 
        elif is_ipv4(external_dns_server_ip):
            external_dns_servers.append(external_dns_server_ip)
        else:
            raise MigrationError(
                messages.INVALID_EXTERNAL_DNS_SERVERS_OPTION % (
                    external_dns_server_ip
                )
            )
        return external_dns_servers
