# -*- coding:utf-8 -*-
# repoman: Checks
# Copyright 2007-2017 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

"""This module contains functions used in Repoman to ascertain the quality
and correctness of an ebuild."""

from __future__ import unicode_literals

import collections
import logging
import os
from copy import deepcopy

from repoman._portage import portage
from repoman.config import load_config
from repoman import _not_installed

# Avoid a circular import issue in py2.7
portage.proxy.lazyimport.lazyimport(globals(),
	'portage.util:stack_lists',
)


def merge(dict1, dict2):
    ''' Return a new dictionary by merging two dictionaries recursively. '''

    result = deepcopy(dict1)

    for key, value in dict2.items():
        if isinstance(value, collections.Mapping):
            result[key] = merge(result.get(key, {}), value)
        else:
            result[key] = deepcopy(dict2[key])

    return result


class LineChecksConfig(object):
	'''Holds our LineChecks configuration data and operation functions'''

	def __init__(self, repo_settings):
		'''Class init

		@param repo_settings: RepoSettings instance
		@param configpaths: ordered list of filepaths to load
		'''
		self.repo_settings = repo_settings
		self.infopaths = None
		self.info_config = None
		self._config = None
		self.usex_supported_eapis = None
		self.in_iuse_supported_eapis = None
		self.get_libdir_supported_eapis = None
		self.eclass_eapi_functions = {}
		self.eclass_export_functions = None
		self.eclass_info = {}
		self.eclass_info_experimental_inherit = {}
		self.errors = {}
		self.set_infopaths()
		self.load_checks_info()

	def set_infopaths(self):
		if _not_installed:
			cnfdir = os.path.realpath(os.path.join(os.path.dirname(
				os.path.dirname(os.path.dirname(os.path.dirname(
				os.path.dirname(__file__))))), 'cnf/linechecks'))
		else:
			cnfdir = os.path.join(portage.const.EPREFIX or '/', 'usr/share/repoman/linechecks')
		repomanpaths = [os.path.join(cnfdir, _file_) for _file_ in os.listdir(cnfdir)]
		logging.debug("LineChecksConfig; repomanpaths: %s", repomanpaths)
		repopaths = [os.path.join(path, 'linechecks.yaml') for path in self.repo_settings.masters_list]
		self.infopaths = repomanpaths + repopaths
		logging.debug("LineChecksConfig; configpaths: %s", self.infopaths)

	def load_checks_info(self, infopaths=None):
		'''load the config files in order

		@param infopaths: ordered list of filepaths to load
		'''
		if infopaths:
			self.infopaths = infopaths
		elif not self.infopaths:
			logging.error("LineChecksConfig; Error: No linechecks.yaml files defined")

		configs = load_config(self.infopaths, 'yaml', self.repo_settings.repoman_settings.valid_versions)
		if configs == {}:
			logging.error("LineChecksConfig: Failed to load a valid 'linechecks.yaml' file at paths: %s", self.infopaths)
			return False
		logging.debug("LineChecksConfig: linechecks.yaml configs: %s", configs)
		self.info_config = configs

		self.errors = self.info_config['errors']
		self.usex_supported_eapis = self.info_config.get('usex_supported_eapis', [])
		self.in_iuse_supported_eapis = self.info_config.get('in_iuse_supported_eapis', [])
		self.eclass_info_experimental_inherit = self.info_config.get('eclass_info_experimental_inherit', [])
		self.get_libdir_supported_eapis = self.in_iuse_supported_eapis
		self.eclass_eapi_functions = {
			"usex": lambda eapi: eapi not in self.usex_supported_eapis,
			"in_iuse": lambda eapi: eapi not in self.in_iuse_supported_eapis,
			"get_libdir": lambda eapi: eapi not in self.get_libdir_supported_eapis,
		}

		# eclasses that export ${ECLASS}_src_(compile|configure|install)
		self.eclass_export_functions = self.info_config.get('eclass_export_functions', [])

		self.eclass_info_experimental_inherit = self.info_config.get('eclass_info_experimental_inherit', {})
		# These are "eclasses are the whole ebuild" type thing.
		try:
			self.eclass_info_experimental_inherit['eutils']['exempt_eclasses'] = self.eclass_export_functions
		except KeyError:
			pass
		try:
			self.eclass_info_experimental_inherit['multilib']['exempt_eclasses'] = self.eclass_export_functions + [
						'autotools', 'libtool', 'multilib-minimal']
		except KeyError:
			pass
