import urllib2
from urlparse import urlparse
import random
import dns.resolver

from application.model.configuration import Configurations


class LoyaltyAvailableInteractor(object):
    def __init__(self, configs):
        # type: (Configurations) -> None

        self.logger = configs.logger
        self.url_to_test = configs.base_url

    def is_loyalty_available(self):
        # type: () -> bool
        try:
            self.has_dns_access()
            self.logger.debug('Url to test: "{}"'.format(self.url_to_test))
            urllib2.urlopen(self.url_to_test, timeout=20)
            self.logger.debug('Test OK')
            return True
        except urllib2.HTTPError as e:
            self.logger.debug('Test OK')
            return True
        except urllib2.URLError as e:
            self.logger.debug('Could not connect to the provided URL', exc_info=e)
            return False
        except ValueError as e:
            self.logger.debug('DNS Server is unreachable', exc_info=e)

    def has_dns_access(self):
        host_name = urlparse(url=self.url_to_test).hostname
        self.logger.debug("Hostname that will be tested: {}".format(host_name))
        name_servers = dns.resolver.Resolver().nameservers
        timeout = 5

        if not name_servers:
            self.logger.debug('DNS Servers not configured')
            return False

        for name_server in name_servers:
            self.logger.debug('Test access DNS Server: {}'.format(name_server))
            request = dns.message.make_query(
                qname=host_name,
                rdtype=dns.rdatatype.A,
            )
            dns_methods = (dns.query.udp, dns.query.tcp)
            for dns_method in dns_methods:
                try:
                    dns_query = dns_method(request, name_server, timeout).rcode()
                    if dns_query == 0:
                        return True
                except Exception as ex:
                    self.logger.warn("Error testing the DNS", exc_info=ex)

        raise ValueError('DNS Error')
