# Copyright 2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

import copy
import io
import logging
import shelve
import sys
import time

import portage
from portage import os
from portage.util import grabdict, grablines
from portage.util._ShelveUnicodeWrapper import ShelveUnicodeWrapper

class Config(object):
	def __init__(self, options, portdb, event_loop):
		self.options = options
		self.portdb = portdb
		self.event_loop = event_loop
		self.added_byte_count = 0
		self.added_file_count = 0
		self.scheduled_deletion_count = 0
		self.delete_count = 0
		self.file_owners = {}
		self.file_failures = {}
		self.start_time = time.time()
		self._open_files = []

		self.log_success = self._open_log('success', options.success_log, 'a')
		self.log_failure = self._open_log('failure', options.failure_log, 'a')

		self.distfiles = None
		if options.distfiles is not None:
			self.distfiles = options.distfiles

		self.mirrors = copy.copy(portdb.settings.thirdpartymirrors())

		if options.mirror_overrides is not None:
			self.mirrors.update(grabdict(options.mirror_overrides))

		if options.mirror_skip is not None:
			for x in options.mirror_skip.split(","):
				self.mirrors[x] = []

		self.whitelist = None
		if options.whitelist_from is not None:
			self.whitelist = set()
			for filename in options.whitelist_from:
				for line in grablines(filename):
					line = line.strip()
					if line and not line.startswith("#"):
						self.whitelist.add(line)

		self.restrict_mirror_exemptions = None
		if options.restrict_mirror_exemptions is not None:
			self.restrict_mirror_exemptions = frozenset(
				options.restrict_mirror_exemptions.split(","))

		self.recycle_db = None
		if options.recycle_db is not None:
			self.recycle_db = self._open_shelve(
				options.recycle_db, 'recycle')

		self.distfiles_db = None
		if options.distfiles_db is not None:
			self.distfiles_db = self._open_shelve(
				options.distfiles_db, 'distfiles')

		self.deletion_db = None
		if options.deletion_db is not None:
			self.deletion_db = self._open_shelve(
				options.deletion_db, 'deletion')

	def _open_log(self, log_desc, log_path, mode):

		if log_path is None or self.options.dry_run:
			log_func = logging.info
			line_format = "%s: %%s" % log_desc
			add_newline = False
			if log_path is not None:
				logging.warning("dry-run: %s log "
					"redirected to logging.info" % log_desc)
		else:
			self._open_files.append(io.open(log_path, mode=mode,
				encoding='utf_8'))
			line_format = "%s\n"
			log_func = self._open_files[-1].write

		return self._LogFormatter(line_format, log_func)

	class _LogFormatter(object):

		__slots__ = ('_line_format', '_log_func')

		def __init__(self, line_format, log_func):
			self._line_format = line_format
			self._log_func = log_func

		def __call__(self, msg):
			self._log_func(self._line_format % (msg,))

	def _open_shelve(self, db_file, db_desc):
		if self.options.dry_run:
			open_flag = "r"
		else:
			open_flag = "c"

		if self.options.dry_run and not os.path.exists(db_file):
			db = {}
		else:
			try:
				db = shelve.open(db_file, flag=open_flag)
			except ImportError as e:
				# ImportError has different attributes for python2 vs. python3
				if (getattr(e, 'name', None) == 'bsddb' or
					getattr(e, 'message', None) == 'No module named bsddb'):
					from bsddb3 import dbshelve
					db = dbshelve.open(db_file, flags=open_flag)

			if sys.hexversion < 0x3000000:
				db = ShelveUnicodeWrapper(db)

		if self.options.dry_run:
			logging.warning("dry-run: %s db opened in readonly mode" % db_desc)
			if not isinstance(db, dict):
				volatile_db = dict((k, db[k]) for k in db)
				db.close()
				db = volatile_db
		else:
			self._open_files.append(db)

		return db

	def __enter__(self):
		return self

	def __exit__(self, exc_type, exc_value, traceback):
		while self._open_files:
			self._open_files.pop().close()
