import logging
import re

logger = logging.getLogger(__name__)
class LogWatch(object):
	"""
	Remote server log monitoring utility.
	
	Logwatch purpose is to retrieve new records written to domain logs since
	watch is started.
	"""
	def __init__(self, domain):
		"""
		Object constructor.

		Arguments:
			domain: 'DomainWebService' object
		"""
		self.domain = domain
		self.log_data = {}
	
	def start(self):
		if not self.domain.runner:
			logger.debug("Cannot read log files without a server object.")
			return
		if not self.domain.error_logs:
			logger.debug("There are no log files specified.")
			return
		for error_log in self.domain.error_logs:
			file_size = self._get_file_size(error_log)
			logger.debug(
				u"Error log '%s' length: '%s'" % (error_log, file_size)
			)
			# remember log file position
			self.log_data[error_log] = file_size

	def get_log_files(self):
		"""List the log files, which are currently being watched."""
		return self.log_data.keys()

	def get_new_records(self, filename):
		"""
		Return new log records.

		Arguments:
			filename: log file name
		Returns:
			New records, that were written into the log file since
			LogWatch.start() is called.
		"""
		if not self.domain.runner:
			return
		if not filename in self.log_data:
			raise LogWatchError(
				u"Logwatch has no data on file '%s'." % filename
			)

		position = self.log_data[filename]
		if not position > 0:
			search_position = "+0"
		else:
			search_position = "+%d" % (position+1)
		stdout = self.domain.runner.sh(
			'/usr/bin/test ! -f {filename} || tail -c {position} {filename}',
			{'filename': filename, 'position': search_position}
		)
		logger.debug(
			"New records in '%s' start from > '%s'" % (filename,
				stdout[:76])
		)
		return stdout

	def _get_file_size(self, filename):
		if not self.domain.runner:
			return
		stdout = self.domain.runner.sh(
			'/usr/bin/test ! -f {filename} || wc -c {filename}',
			{'filename': filename}
		)
		# parse a string like '2048 filename', where '2048' is the file size
		match = re.search('^\d+', stdout)
		if match:
			return int(match.group(0))
		else:
			logger.debug("Cannot get size of '%s'" % filename)

class LogWatchError(Exception):
	pass
