#!/usr/bin/env python3
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License along
#   with this program; if not, write to the Free Software Foundation, Inc.,
#   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

# Marc Schoechlin <ms@256bit.org>

import argparse
import json
import os
import re
import sys

config_default = {
}
####################################################################################
#### HELPERS

import smtplib
import sys
import traceback
import time
import uuid


def my_random_string(string_length=10):
    """Returns a random string of length string_length."""
    random = str(uuid.uuid4())  # Convert UUID format to a Python string.
    random = random.upper()  # Make all characters uppercase.
    random = random.replace("-", "")  # Remove the UUID '-'.
    return random[0:string_length]  # Return the random string.


def read_config(config_file):
    config = config_default
    if os.path.exists(config_file):
        if args.debug:
            sys.stderr.write("reading config file %s\n" % config_file)
        try:
            fh = open(config_file, 'r')
            content = fh.read()

            # Remove multiline comments
            content = re.sub('^\s*/\*.*?\*/\s*', '', content, 0, re.DOTALL | re.MULTILINE)
            # Remove single line comments
            content = re.sub('^\s*//.*$\n', '', content, 0, re.MULTILINE)

            config = json.loads(content)

            fh.close()
        except FileNotFoundError:
            sys.stderr.write("Config file does not exist\n")
        except PermissionError:
            sys.stderr.write("Could not read config file\n")
        except json.decoder.JSONDecodeError:
            sys.stderr.write("Could not parse JSON config file\n")
        except:
            sys.stderr.write("An unexpected error occured while reading config file\n")

    return config

# https://yuji.wordpress.com/2011/06/22/python-imaplib-imap-example-with-gmail/
def check_smtp_send(smtp_config):

    try:
        ident = smtp_config["ident"]
        fromaddr = smtp_config["from"]
        toaddr = smtp_config["to"]
        server_name = smtp_config["server"]
        port = smtp_config["port"]
        login = smtp_config["login"]
        password = smtp_config["password"]
    except:
        sys.stderr.write("missing parameters in ")
        sys.stdout.write("0\n")

    msg = ("From: %s\r\nTo: %s\r\n\r\n" % (fromaddr, toaddr))

    id_nr = int(time.time())
    msg += "Subject: MAIL ROUNDTRIP TESTMAIL %s :: %s" % (ident, id_nr)
    msg += "\n\n"
    for n in range(1, 100):
        msg += my_random_string(n) + " "

    try:
        server = smtplib.SMTP(server_name, port)
        if args.debug:
            server.set_debuglevel(1)
        server.starttls()
        server.ehlo()
        server.login(login, password)
        server.sendmail(fromaddr, toaddr, msg)
        server.quit()
    except Exception as e:
        print("Exception happened:")
        sys.stderr.write('*' * 60 + "\n")
        sys.stderr.write("*** " + str(e) + "\n")
        sys.stderr.write('*' * 60 + "\n")
        sys.stderr.write("\n")
        traceback.print_exc(file=sys.stderr)
        sys.stderr.write('-' * 60 + "\n")
        sys.stdout("1\n")
        sys.exit(0)
    sys.stdout.write("0\n")
    sys.exit(0)

def check_imap_receive(imap_config):

    try:
        ident = imap_config["ident"]
        fromaddr = imap_config["from"]
        toaddr = imap_config["to"]
        server_name = imap_config["server"]
        port = imap_config["port"]
        login = imap_config["login"]
        password = imap_config["password"]
    except:
        sys.stderr.write("missing parameters in ")
        sys.stdout.write("0\n")

    msg = ("From: %s\r\nTo: %s\r\n\r\n" % (fromaddr, toaddr))

    id_nr = int(time.time())
    msg += "Subject: MAIL ROUNDTRIP TESTMAIL %s :: %s" % (ident, id_nr)
    msg += "\n\n"
    for n in range(1, 100):
        msg += my_random_string(n) + " "

    try:
        server = smtplib.SMTP(server_name, port)
        if args.debug:
            server.set_debuglevel(1)
        server.starttls()
        server.ehlo()
        server.login(login, password)
        server.sendmail(fromaddr, toaddr, msg)
        server.quit()
    except Exception as e:
        print("Exception happened:")
        sys.stderr.write('*' * 60 + "\n")
        sys.stderr.write("*** " + str(e) + "\n")
        sys.stderr.write('*' * 60 + "\n")
        sys.stderr.write("\n")
        traceback.print_exc(file=sys.stderr)
        sys.stderr.write('-' * 60 + "\n")
        sys.stdout("1\n")
        sys.exit(0)
    sys.stdout.write("0\n")
    sys.exit(0)

####################################################################################
#### MAIN

parser = argparse.ArgumentParser(
    description='perform device disovery for zabbix',
    formatter_class=argparse.RawTextHelpFormatter,
    epilog='''Example json configuration file:
{
	"smtp": [{
		"ident": "myserver",
		"type": "smtp",
		"server": "foo.bar.serverfarm.st",
		"login": "bar",
		"password": "pass123",
		"from": "lalal@blala.de",
		"freq": "300"
	}],
	"imap": [{
		"ident": "remoteserver",
		"type": "imap",
		"server": "imap.foobar.serverfarm.st",
		"login": "bar",
		"password": "pass",
		"freq": "300"
	}]
}


    '''
)

parser.add_argument(
    '--debug',
    help='Output debug information',
    action='store_true',
)

parser_group = parser.add_mutually_exclusive_group(required=True)

parser_group.add_argument(
    '--discovery',
    help='Output discovery information',
    action='store_true',
)

parser_group.add_argument(
    '--smtp',
    nargs='?',
    type=str,
    help='configuration file',
    default=None,
)

parser_group.add_argument(
    '--imap',
    nargs='?',
    type=str,
    help='configuration file',
    default=None,
)

parser.add_argument(
    '--config',
    nargs='?',
    type=str,
    help='configuration file',
    default=None,
    required=True,
)

args = parser.parse_args()

devices_discovered = {'data': []}

# read the config
if args.config is not None:
    config = read_config(args.config)
else:
    config = config_default

if args.debug:
    sys.stderr.write("** Effective config:\n%s\n" % json.dumps(config, indent=2))

ret = 1
if args.smtp is not None:
    for config_c in (config["smtp"]):
        if config_c["ident"] == args.smtp:
            check_smtp_send(config_c)
            break

if args.imap is not None:
    for config_c in (config["imap"]):
        if config_c["ident"] == args.imap:
            check_imap_receive(config_c)
            break



sys.exit(0)
