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

import io
import re
import subprocess
import sys

try:
	from configparser import Error as ConfigParserError, RawConfigParser
except ImportError:
	from ConfigParser import Error as ConfigParserError, RawConfigParser

from portage import _encodings, _unicode_encode, _unicode_decode
from portage.util import writemsg

def parse_desktop_entry(path):
	"""
	Parse the given file with RawConfigParser and return the
	result. This may raise an IOError from io.open(), or a
	ParsingError from RawConfigParser.
	"""
	parser = RawConfigParser()

	# use read_file/readfp in order to control decoding of unicode
	try:
		# Python >=3.2
		read_file = parser.read_file
	except AttributeError:
		read_file = parser.readfp

	with io.open(_unicode_encode(path,
		encoding=_encodings['fs'], errors='strict'),
		mode='r', encoding=_encodings['repo.content'],
		errors='replace') as f:
		content = f.read()

	# In Python 3.2, read_file does not support bytes in file names
	# (see bug #429544), so use StringIO to hide the file name.
	read_file(io.StringIO(content))

	return parser

_trivial_warnings = re.compile(r' looks redundant with value ')

_ignored_errors = (
		# Ignore error for emacs.desktop:
		# https://bugs.freedesktop.org/show_bug.cgi?id=35844#c6
		'error: (will be fatal in the future): value "TextEditor" in key "Categories" in group "Desktop Entry" requires another category to be present among the following categories: Utility',
		'warning: key "Encoding" in group "Desktop Entry" is deprecated'
)

def validate_desktop_entry(path):
	args = ["desktop-file-validate", path]
	if sys.hexversion < 0x3000000 or sys.hexversion >= 0x3020000:
		# Python 3.1 does not support bytes in Popen args.
		args = [_unicode_encode(x, errors='strict') for x in args]
	proc = subprocess.Popen(args,
		stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
	output_lines = _unicode_decode(proc.communicate()[0]).splitlines()
	proc.wait()

	if output_lines:
		filtered_output = []
		for line in output_lines:
			msg = line[len(path)+2:]
			# "hint:" output is new in desktop-file-utils-0.21
			if msg.startswith('hint: ') or msg in _ignored_errors:
				continue
			filtered_output.append(line)
		output_lines = filtered_output

	if output_lines:
		output_lines = [line for line in output_lines
			if _trivial_warnings.search(line) is None]

	return output_lines

if __name__ == "__main__":
	for arg in sys.argv[1:]:
		for line in validate_desktop_entry(arg):
			writemsg(line + "\n", noiselevel=-1)
