# vim:fileencoding=utf-8:noet

from __future__ import absolute_import
import sys


def get_segment_key(segment, theme_configs, key, module=None, default=None):
	try:
		return segment[key]
	except KeyError:
		if 'name' in segment:
			name = segment['name']
			for theme_config in theme_configs:
				if 'segment_data' in theme_config:
					for segment_key in ((module + '.' + name, name) if module else (name,)):
						try:
							return theme_config['segment_data'][segment_key][key]
						except KeyError:
							pass
	return default


def get_function(data, segment):
	oldpath = sys.path
	sys.path = data['path'] + sys.path
	segment_module = str(segment.get('module', data['default_module']))
	try:
		return None, getattr(__import__(segment_module, fromlist=[segment['name']]), segment['name']), segment_module
	finally:
		sys.path = oldpath


def get_string(data, segment):
	return data['get_key'](segment, None, 'contents'), None, None


def get_filler(data, segment):
	return None, None, None


segment_getters = {
	"function": get_function,
	"string": get_string,
	"filler": get_filler,
}


def gen_segment_getter(ext, path, theme_configs, default_module=None):
	data = {
		'default_module': default_module or 'powerline.segments.' + ext,
		'path': path,
	}

	def get_key(segment, module, key, default=None):
		return get_segment_key(segment, theme_configs, key, module, default)
	data['get_key'] = get_key

	def get(segment, side):
		segment_type = segment.get('type', 'function')
		try:
			get_segment_info = segment_getters[segment_type]
		except KeyError:
			raise TypeError('Unknown segment type: {0}'.format(segment_type))
		contents, contents_func, module = get_segment_info(data, segment)
		highlight_group = segment_type != 'function' and segment.get('highlight_group') or segment.get('name')
		return {
			'name': segment.get('name'),
			'type': segment_type,
			'highlight_group': highlight_group,
			'divider_highlight_group': None,
			'before': get_key(segment, module, 'before', ''),
			'after': get_key(segment, module, 'after', ''),
			'contents_func': contents_func,
			'contents': contents,
			'args': get_key(segment, module, 'args', {}) if segment_type == 'function' else {},
			'priority': segment.get('priority', None),
			'draw_hard_divider': segment.get('draw_hard_divider', True),
			'draw_soft_divider': segment.get('draw_soft_divider', True),
			'draw_inner_divider': segment.get('draw_inner_divider', False),
			'side': side,
			'exclude_modes': segment.get('exclude_modes', []),
			'include_modes': segment.get('include_modes', []),
			'width': segment.get('width'),
			'align': segment.get('align', 'l'),
			'shutdown': getattr(contents_func, 'shutdown', None),
			'startup': getattr(contents_func, 'startup', None),
			'_rendered_raw': '',
			'_rendered_hl': '',
			'_len': 0,
			'_space_left': 0,
			'_space_right': 0,
		}

	return get

@@ -1627,16 +1627,25 @@
 _type))%0A
+%0A%09%09try:%0A%09
 %09%09conten
@@ -1710,25 +1710,158 @@
 )%0A%09%09
-highlight_group =
+except Exception as e:%0A%09%09%09pl.exception('Failed to generate segment from %7B0!r%7D: %7B1%7D', segment, str(e), prefix='segment_generator')%0A%09%09%09return None%0A%0A%09%09if
  seg
@@ -1870,17 +1870,17 @@
 nt_type 
-!
+=
 = 'funct
@@ -1887,12 +1887,109 @@
 ion'
- and
+:%0A%09%09%09highlight_group = %5Bmodule + '.' + segment%5B'name'%5D, segment%5B'name'%5D%5D%0A%09%09else:%0A%09%09%09highlight_group =
  seg
@@ -2039,16 +2039,17 @@
 'name')%0A
+%0A
 %09%09return

Use different default for functions