import re
import urllib2
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, code: {}'.format(e.code))
            return True
        except urllib2.URLError as e:
            self.logger.debug('Test failed with reason: "{}"'.format(e.reason))
            return False
        except ValueError as e:
            self.logger.debug('DNS Server is unreacheble: {}'.format(e))

    def has_dns_access(self):
        name_servers = dns.resolver.Resolver().nameservers
        timeout = 5
        url_without_protocol = re.sub('^https?://', '', self.url_to_test)

        if name_servers:
            dns_server = random.choice(name_servers)
            self.logger.debug('Test access DNS Server: {}'.format(dns_server))
            request = dns.message.make_query(url_without_protocol, dns.rdatatype.A)
            dns_query = dns.query.tcp(request, dns_server, timeout).rcode()
            if dns_query == 0:
                return True
            else:
                raise ValueError('DNS Error')

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