#!/usr/bin/python3
# -*- coding: utf-8 -*-

# {{ ansible_managed | comment }}

# BUILTIN
import sys
import unittest
import shutil
import os
import pwd
import argparse
import smtplib
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from os.path import basename
import email

# CUSTOM
import data_source_users

# Change this, to switch to another signature. For example, a new signature for a trade fair.

# Normal signature
#SIGNATURE_TEMPLATE_PATH = 'signature_template_innovation_servicehotline.html'
#SIGNATURE_EVO_TEMPLATE_PATH = 'signature_template_evolution_servicehotline.html'

# Messe signature
#SIGNATURE_TEMPLATE_PATH = 'signature_template_innovation_messe.html'
#SIGNATURE_EVO_TEMPLATE_PATH = 'signature_template_evolution_messe.html'

# Webinar signature
#SIGNATURE_TEMPLATE_PATH = 'signature_template_innovation_webinare.html'
#SIGNATURE_EVO_TEMPLATE_PATH = 'signature_template_evolution_webinare.html'

# Industrial pioneer (for 21.04.01)
#SIGNATURE_TEMPLATE_PATH = 'signature_template_innovation_210331_industrial_pioneers.html'
#SIGNATURE_EVO_TEMPLATE_PATH = 'signature_template_evolution_210331_industrial_pioneers.html'

# Christmas signature
SIGNATURE_TEMPLATE_PATH = 'signature_template_innovation_weihnachten.html'
SIGNATURE_EVO_TEMPLATE_PATH = 'signature_template_evolution_weihnachten.html'

# Easter signature
#SIGNATURE_TEMPLATE_PATH = 'signature_template_innovation_ostern.html'
#SIGNATURE_EVO_TEMPLATE_PATH = 'signature_template_evolution_ostern.html'

# Jubiläums Signatur
#SIGNATURE_TEMPLATE_PATH = 'signature_template_innovation_jubilaeum.html'
#SIGNATURE_EVO_TEMPLATE_PATH = 'signature_template_evolution_jubilaeum.html'

HOMES_PATH = '/home/{}/'


def escape_html(html):
    '''
    Will escape some special characters like "ü", "?"
    '''
    esc_dict = {
        'ö':'&ouml;',
        'Ö':'&Ouml;',
        'ü':'&uuml;',
        'Ü':'&Uuml;',
        'ä':'&auml;',
        'Ä':'&Auml;',
        'ß':'&szlig;',
        'Á':'&Aacute;',
        'á':'&aacute;',
        'À':'&Agrave;',
        'à':'&agrave;',
    }
    for esc_char in list(esc_dict.keys()):
        html = html.replace(esc_char, esc_dict[esc_char])
    return html


def send_signature(mail=None, attachment_path=None):
    '''
    Sends signature to user
    '''
    if not mail:
        print('Got no email address')
        return
    else:
        mail = mail.strip()
    print(('Will send now signature to ' + str(mail) + ' with attachment ' + str(attachment_path)))
    smtp = smtplib.SMTP()
    smtp.connect(
        host='localhost',
        port=25
    )
    msg = MIMEMultipart()
    msg['Subject'] = 'Neue E-Mail Signatur'
    msg['From'] = 'noreply@perfact.de'
    msg['To'] = mail
    msg.attach(
        MIMEText(
            open('signature_mail_text.html','r').read(),
            'html',
            'utf-8'
        )
    )
    part = MIMEApplication(
        open(attachment_path, "r").read(),
        #'html',
        #email.encoders.encode_noop,
        Name=basename(attachment_path),
    )
    part['Content-Disposition'] = 'attachment; filename="%s"' % basename(attachment_path)
    msg.attach(part)
    smtp.sendmail(msg['from'], msg['to'], msg.as_string())
    smtp.close()
    return


def get_local_data():
    '''
    gets user data from local python file containing dictionary with user infos
    '''
    for key in data_source_users.data:
        infodict = data_source_users.data[key]
        # set signature_name if not set
        if not 'signature_name' in infodict:
            infodict['signature_name'] = infodict['vorname']+" "+infodict['nachname']
        if infodict['evo'] is True:
            path = SIGNATURE_EVO_TEMPLATE_PATH
        else:
            path = SIGNATURE_TEMPLATE_PATH
        with open(path, 'r') as template:  # WICHTIG
            template = template.read()
        yield infodict, template


def fill_template():

    '''
    fill signature template from data_source
    '''
    for infodict, template in get_local_data():
        replace_map = {
            #'#vorname#': infodict['vorname'],
            #'#nachname#': infodict['nachname'],
            '#signature_name#': infodict['signature_name'],
            '#durchwahl#': infodict['durchwahl'],
            '#mobil#':infodict['mobil'],
            '#positionenglisch#': infodict['positioneng'],
            '#position#': infodict['position'],
            '#email#': infodict['email']
        }


        signature = template
        for punch_key, punch_value in list(replace_map.items()):
            signature = signature.replace(punch_key, punch_value)

        yield signature, infodict['username'].lower(), infodict['signature_per_mail'], infodict['email']


def write_signature(args):
    '''
    write new signature to file
    signature = html file in string
    username = self explaining
    send_mail = Boolean if wanting to send the signature via mail
    mail = mail address
    '''

    for signature, username, send_mail, mail in fill_template():
        signature = escape_html(signature)
        if args.user:
            if username == args.user:
                home_path = HOMES_PATH.format(username)
                signature_filename = 'signature_automatic.html'
                print(('Writing signature file {0} for user {1}'.format(signature_filename, username)))
                with open('signature_out.html', 'w') as template_out:
                    template_out.write(signature)
                print(('Moving new signature to {}'.format(home_path)))
                if args.dryrun:
                    print('Would move new signature.')
                else:
                    shutil.move('signature_out.html',
                                home_path + signature_filename)
                    # chown of the moved file
                    # errorhandling if user not exits
                    try:
                      userid = pwd.getpwnam(username).pw_uid
                      groupid = pwd.getpwnam(username).pw_gid
                      os.chown(home_path + signature_filename, userid, groupid)
                    except Exception as e:
                      print(e)

                    if send_mail:
                        send_signature(mail, home_path + signature_filename)
                return
            else:
                continue
        else:
            home_path = HOMES_PATH.format(username)
            signature_filename = 'signature_automatic.html'
            print(('Writing signature file {0} for user {1}'.format(signature_filename, username)))
            with open('signature_out.html', 'w') as template_out:
                template_out.write(signature)
            print(('Moving new signature to {}'.format(home_path)))
            if args.dryrun:
                print('Would move new signature.')
            else:
                try:
                    shutil.move('signature_out.html',
                              home_path + signature_filename)
                except Exception as e:
                    print(e)
                    continue
                # chown of the moved file
                # errorhandling if user not exits
                try:
                    userid = pwd.getpwnam(username).pw_uid
                    groupid = pwd.getpwnam(username).pw_gid
                    os.chown(home_path + signature_filename, userid, groupid)
                except Exception as e:
                    print(e)
                    continue

                if send_mail:
                    send_signature(mail, home_path + signature_filename)


if __name__ == '__main__':
    '''
    only start writing signature when called as main programm, not if imported
    as library!
    '''
    parser = argparse.ArgumentParser(
        description='''
        This is will update the e-mail signatures
        '''
    )
    parser.add_argument(
        '--user',
        '-u',
        action='store',
        dest='user',
        help='''Run this script only for one user'''
    )
    parser.add_argument(
        '--dryrun',
        '-d',
        action='store_true',
        dest='dryrun',
        help='''Dryrun!'''
    )
    args = parser.parse_args()

    write_signature(args)
    print('---------------------Signature ready---------------------')
