# -*- python-mode -*-
# -*- coding: UTF-8 -*-

## Copyright (C) 2012-2013  Daniel Pavel
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License along
## with this program; if not, write to the Free Software Foundation, Inc.,
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

import os as _os
import os.path as _path
from json import load as _json_load, dump as _json_save

from logging import getLogger, DEBUG as _DEBUG, INFO as _INFO
_log = getLogger(__name__)
del getLogger

_XDG_CONFIG_HOME = _os.environ.get('XDG_CONFIG_HOME') or _path.expanduser(_path.join('~', '.config'))
_file_path = _path.join(_XDG_CONFIG_HOME, 'solaar', 'config.json')


from solaar import __version__
_KEY_VERSION = '_version'
_KEY_NAME = '_name'
_configuration = {}



def _load():
	if _path.isfile(_file_path):
		loaded_configuration = {}
		try:
			with open(_file_path, 'r') as config_file:
				loaded_configuration = _json_load(config_file)
		except:
			_log.error("failed to load from %s", _file_path)

		# loaded_configuration.update(_configuration)
		_configuration.clear()
		_configuration.update(loaded_configuration)

	if _log.isEnabledFor(_DEBUG):
		_log.debug("load => %s", _configuration)

	_cleanup(_configuration)
	_configuration[_KEY_VERSION] = __version__
	return _configuration


def save():
	# don't save if the configuration hasn't been loaded
	if _KEY_VERSION not in _configuration:
		return

	dirname = _os.path.dirname(_file_path)
	if not _path.isdir(dirname):
		try:
			_os.makedirs(dirname)
		except:
			_log.error("failed to create %s", dirname)
			return False

	_cleanup(_configuration)

	try:
		with open(_file_path, 'w') as config_file:
			_json_save(_configuration, config_file, skipkeys=True, indent=2, sort_keys=True)

		if _log.isEnabledFor(_INFO):
			_log.info("saved %s to %s", _configuration, _file_path)
		return True
	except:
		_log.error("failed to save to %s", _file_path)


def _cleanup(d):
	# remove None values from the dict
	for key in list(d.keys()):
		value = d.get(key)
		if value is None:
			del d[key]
		elif isinstance(value, dict):
			_cleanup(value)


def _device_key(device):
	return '%s:%s' % (device.wpid, device.serial)


class _DeviceEntry(dict):
	def __init__(self, *args, **kwargs):
		super(_DeviceEntry, self).__init__(*args, **kwargs)

	def __setitem__(self, key, value):
		super(_DeviceEntry, self).__setitem__(key, value)
		save()


def _device_entry(device):
	if not _configuration:
		_load()

	device_key = _device_key(device)
	c = _configuration.get(device_key) or {}

	if not isinstance(c, _DeviceEntry):
		c[_KEY_NAME] = device.name
		c = _DeviceEntry(c)
		_configuration[device_key] = c

	return c


def attach_to(device):
	"""Apply the last saved configuration to a device."""
	if not _configuration:
		_load()

	persister = _device_entry(device)
	for s in device.settings:
		if s.persister is None:
			s.persister = persister
		assert s.persister == persister
