# 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.warn(("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:
			db = shelve.open(db_file, flag=open_flag)
			if sys.hexversion < 0x3000000:
				db = ShelveUnicodeWrapper(db)

		if self.options.dry_run:
			logging.warn("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()
