# portage.py -- core Portage functionality
# Copyright 1998-2004 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

# Since python ebuilds remove the 'email' module when USE=build
# is enabled, use a local import so that
# portage.proxy.lazyimport._preload_portage_submodules()
# can load this module even though the 'email' module is missing.
# The elog mail modules won't work, but at least an ImportError
# won't cause portage to crash during stage builds. Since the
# 'smtlib' module imports the 'email' module, that's imported
# locally as well.

import socket
import sys
import time

from portage import os
from portage import _encodings
from portage import _unicode_decode, _unicode_encode
from portage.localization import _
import portage

if sys.hexversion >= 0x3000000:
	basestring = str

def TextMessage(_text):
	from email.mime.text import MIMEText
	mimetext = MIMEText(_text)
	if sys.hexversion >= 0x3000000:
		mimetext.set_charset("UTF-8")
	return mimetext

def create_message(sender, recipient, subject, body, attachments=None):

	from email.header import Header
	from email.mime.base import MIMEBase as BaseMessage
	from email.mime.multipart import MIMEMultipart as MultipartMessage

	if sys.hexversion < 0x3000000:
		sender = _unicode_encode(sender,
			encoding=_encodings['content'], errors='strict')
		recipient = _unicode_encode(recipient,
			encoding=_encodings['content'], errors='strict')
		subject = _unicode_encode(subject,
			encoding=_encodings['content'], errors='backslashreplace')
		body = _unicode_encode(body,
			encoding=_encodings['content'], errors='backslashreplace')

	if attachments == None:
		mymessage = TextMessage(body)
	else:
		mymessage = MultipartMessage()
		mymessage.attach(TextMessage(body))
		for x in attachments:
			if isinstance(x, BaseMessage):
				mymessage.attach(x)
			elif isinstance(x, basestring):
				if sys.hexversion < 0x3000000:
					x = _unicode_encode(x,
						encoding=_encodings['content'],
						errors='backslashreplace')
				mymessage.attach(TextMessage(x))
			else:
				raise portage.exception.PortageException(_("Can't handle type of attachment: %s") % type(x))

	mymessage.set_unixfrom(sender)
	mymessage["To"] = recipient
	mymessage["From"] = sender
	# Use Header as a workaround so that long subject lines are wrapped
	# correctly by <=python-2.6 (gentoo bug #263370, python issue #1974).
	mymessage["Subject"] = Header(subject)
	mymessage["Date"] = time.strftime("%a, %d %b %Y %H:%M:%S %z")
	
	return mymessage

def send_mail(mysettings, message):

	import smtplib

	mymailhost = "localhost"
	mymailport = 25
	mymailuser = ""
	mymailpasswd = ""
	myrecipient = "root@localhost"
	
	# Syntax for PORTAGE_ELOG_MAILURI (if defined):
	# adress [[user:passwd@]mailserver[:port]]
	# where adress:     recipient adress
	#       user:       username for smtp auth (defaults to none)
	#       passwd:     password for smtp auth (defaults to none)
	#       mailserver: smtp server that should be used to deliver the mail (defaults to localhost)
	#					alternatively this can also be the absolute path to a sendmail binary if you don't want to use smtp
	#       port:       port to use on the given smtp server (defaults to 25, values > 100000 indicate that starttls should be used on (port-100000))
	if " " in mysettings["PORTAGE_ELOG_MAILURI"]:
		myrecipient, mymailuri = mysettings["PORTAGE_ELOG_MAILURI"].split()
		if "@" in mymailuri:
			myauthdata, myconndata = mymailuri.rsplit("@", 1)
			try:
				mymailuser,mymailpasswd = myauthdata.split(":")
			except ValueError:
				print(_("!!! invalid SMTP AUTH configuration, trying unauthenticated ..."))
		else:
			myconndata = mymailuri
		if ":" in myconndata:
			mymailhost,mymailport = myconndata.split(":")
		else:
			mymailhost = myconndata
	else:
		myrecipient = mysettings["PORTAGE_ELOG_MAILURI"]
	
	myfrom = message.get("From")

	if sys.hexversion < 0x3000000:
		myrecipient = _unicode_encode(myrecipient,
			encoding=_encodings['content'], errors='strict')
		mymailhost = _unicode_encode(mymailhost,
			encoding=_encodings['content'], errors='strict')
		mymailport = _unicode_encode(mymailport,
			encoding=_encodings['content'], errors='strict')
		myfrom = _unicode_encode(myfrom,
			encoding=_encodings['content'], errors='strict')
		mymailuser = _unicode_encode(mymailuser,
			encoding=_encodings['content'], errors='strict')
		mymailpasswd = _unicode_encode(mymailpasswd,
			encoding=_encodings['content'], errors='strict')

	# user wants to use a sendmail binary instead of smtp
	if mymailhost[0] == os.sep and os.path.exists(mymailhost):
		fd = os.popen(mymailhost+" -f "+myfrom+" "+myrecipient, "w")
		fd.write(message.as_string())
		if fd.close() != None:
			sys.stderr.write(_("!!! %s returned with a non-zero exit code. This generally indicates an error.\n") % mymailhost)
	else:
		try:
			if int(mymailport) > 100000:
				myconn = smtplib.SMTP(mymailhost, int(mymailport) - 100000)
				myconn.ehlo()
				if not myconn.has_extn("STARTTLS"):
					raise portage.exception.PortageException(_("!!! TLS support requested for logmail but not suported by server"))
				myconn.starttls()
				myconn.ehlo()
			else:
				myconn = smtplib.SMTP(mymailhost, mymailport)
			if mymailuser != "" and mymailpasswd != "":
				myconn.login(mymailuser, mymailpasswd)

			message_str = message.as_string()
			if sys.hexversion >= 0x3000000:
				# Force ascii encoding in order to avoid UnicodeEncodeError
				# from smtplib.sendmail with python3 (bug #291331).
				message_str = _unicode_encode(message_str,
					encoding='ascii', errors='backslashreplace')
				message_str = _unicode_decode(message_str,
					encoding='ascii', errors='replace')

			myconn.sendmail(myfrom, myrecipient, message_str)
			myconn.quit()
		except smtplib.SMTPException as e:
			raise portage.exception.PortageException(_("!!! An error occured while trying to send logmail:\n")+str(e))
		except socket.error as e:
			raise portage.exception.PortageException(_("!!! A network error occured while trying to send logmail:\n%s\nSure you configured PORTAGE_ELOG_MAILURI correctly?") % str(e))
	return
	
