import logging

from parallels.hosting_check import DomainIssue
from parallels.hosting_check import Severity, DNSIssueType
from parallels.hosting_check.utils.dns_utils import DnsRequestTimeoutException
from parallels.hosting_check.utils.dns_utils import get_difference

from parallels.hosting_check.messages import MSG

logger = logging.getLogger(__name__)

class DNSChecker:
	def __init__(
		self,
		max_difference_lines=3, save_external_report_data_function=None, 
		dns_server_name='PPA DNS server',
		difference_file_panel_id='ppa'
	):
		self.max_difference_lines = max_difference_lines
		self.save_external_report_data_function = \
			save_external_report_data_function
		self.dns_server_name = dns_server_name
		self.difference_file_panel_id = difference_file_panel_id

	def check(self, domains_to_check):
		issues = []

		def add_issue(severity, category, problem):
			issues.append(
				DomainIssue(
					domain_name=domain_to_check.domain_name,
					severity=severity,
					category=category,
					problem=problem
				)
			)

		for domain_to_check in domains_to_check:
			for dns_server_ip in domain_to_check.dns_servers:
				try:
					difference = get_difference(
						domain_to_check.dns_records, dns_server_ip
					)

					if len(difference) > 0:
						if (
							len(difference) <= self.max_difference_lines 
							or 
							self.save_external_report_data_function is None
						): 
							# put all differences to screen immediately
							difference_str = MSG(
								'dns_difference_full',
								difference=u"\n".join(difference)
							)
						else:
							# put first 3 differences to screen as an example,
							# put all other differences into a separate file
							filename = self.save_external_report_data_function(
								"dns.%s.%s.difference.%s" % (
									self.difference_file_panel_id, 
									dns_server_ip, domain_to_check.domain_name
								), 
								MSG(
									'dns_file_difference',
									server_ip=dns_server_ip,
									difference=u"\n".join(difference)
								)
							)
							difference_str = MSG(
								'dns_difference_example',
								example_difference=u"\n".join(difference[:3]),
								filename=filename
							)

						add_issue(
							severity=Severity.ERROR, 
							category=DNSIssueType.DIFFERENT_RECORDS,
							problem=MSG(
								DNSIssueType.DIFFERENT_RECORDS,
								server_ip=dns_server_ip,
								difference=difference_str
							)
						)
				except DnsRequestTimeoutException, e:
					logger.debug(u"Exception:", exc_info=e)
					# do not return any report comparing records - just a
					# timeout message
					add_issue(
						severity=Severity.ERROR,
						category=DNSIssueType.DNS_SERVER_TIMEOUT,
						problem=MSG(
							DNSIssueType.DNS_SERVER_TIMEOUT,
							server_name=self.dns_server_name,
							server_ip=e.server_ip
						)
					)
				except KeyboardInterrupt:
					# for compatibility with python 2.4
					raise
				except Exception, e:
					logger.debug(u"Exception:", exc_info=e)
					# do not return any report comparing records - just a
					# general failure message
					add_issue(
						severity=Severity.WARNING,
						category=DNSIssueType.INTERNAL_ERROR,
						problem=MSG(
							DNSIssueType.INTERNAL_ERROR,
							reason=str(e),
							server_name=self.dns_server_name, 
							server_ip=dns_server_ip
						)
					)
		return issues