# encoding: utf-8

import logging
import subprocess
import sys
from pipes import quote

class MigrationError(Exception):
	pass

class MigrationConfigurationFileError(Exception):
	pass

class MigrationNoContextError(Exception):
	pass

logger = logging.getLogger(__name__)

def run_and_check_local_command(command, stdin_content=None, output_codepage='utf-8'):
	exit_code, stdout_str, stderr_str = local_command_exec(
			command, stdin_content, output_codepage)
	if exit_code != 0:
		raise MigrationError(u"Failed to execute command '%s', non-zero exit code" % (u" ".join([quote(c) for c in command])))
	return stdout_str, stderr_str

def local_command_exec(
		command, stdin_content=None, output_codepage='utf-8',
		error_policy='strict'):
	try:
		if type(command) is list or type(command) is tuple:
			command_str = ' '.join([quote(c) for c in command])
		else:
			command_str = command
		logger.debug(u"Call local command: %s" % (command_str,))

		p = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
		stdout_str, stderr_str = [s.decode(output_codepage, error_policy) for s in p.communicate(stdin_content)]
		logger.debug(u"Command stdout: %s", stdout_str)
		logger.debug(u"Command stderr: %s", stderr_str)
		logger.debug(u"Command exit code: %s", p.returncode)
		return p.returncode, stdout_str, stderr_str
	except UnicodeError:
		raise # fatal error that should be passed above as is for better logging
	except Exception as e:
		logger.debug(u'Exception:', exc_info=e)
		raise Exception(u"Failed to execute local command '%s': %s" % (u" ".join([quote(c) for c in command]), e,)), None, sys.exc_info()[2]

def version_tuple(version):
	"""Convert string product version to a tuple of ints"""
	return tuple(map(int, version.split('.')))

