#!/usr/bin/env python3

import os
import sys

import smtplib
import ssl
from email.message import EmailMessage
from configparser import ConfigParser

PACKAGE_TYPES = "arch"


def get_xdg_dir(env_var: str, fallback_dir: str) -> str:
    xdg_dir = os.getenv(env_var)
    if xdg_dir is None or xdg_dir == "":
        xdg_dir = "{}/{}".format(get_home(), fallback_dir)

    return xdg_dir


def get_home() -> str:
    home = os.getenv("HOME")

    if home is None or home == "":
        print("Error: $HOME not accessible")
        sys.exit(1)

    return home


class ConfigFile:
    def __init__(self, path: str):
        config_parser = self.get_config_parser(path)

        try:
            self.smtp_server = config_parser["dummy_section"]["smtp_server"]
            self.smtp_port = int(config_parser["dummy_section"]["smtp_port"])
            self.smtp_connection = config_parser["dummy_section"][
                "smtp_connection"
            ]
            if self.smtp_connection not in ("ssl", "starttls"):
                print(
                    "Error: 'smtp_connection' must be either 'ssl' or 'starttls'"
                )
                sys.exit(1)
            self.from_address = config_parser["dummy_section"]["from_address"]
            self.password = config_parser["dummy_section"]["password"]
            self.to_address = config_parser["dummy_section"]["to_address"]
            self.log_file = config_parser["dummy_section"]["log_file"]
            self.tail_value = int(config_parser["dummy_section"]["tail_value"])
            self.package_type = config_parser["dummy_section"]["package_type"]

            if self.package_type not in [PACKAGE_TYPES]:
                print(
                    "Error: use one of the supported packges types: {}".format(
                        PACKAGE_TYPES
                    )
                )
                sys.exit(1)
        except KeyError as missing_entry:
            print("Error: needed config entry missing {}".format(missing_entry))
            sys.exit(1)
        except ValueError as wrong_value:
            print("Error: {}".format(wrong_value))
            sys.exit(1)

    def get_config_parser(self, config_path) -> ConfigParser:
        try:
            with open(config_path, "r", encoding="utf-8") as config_reader:
                config_string = "[dummy_section]\n" + config_reader.read()
        except (FileNotFoundError, PermissionError, IOError):
            print("Error: could not access config at '{}'".format(config_path))
            sys.exit(1)

        config_parser = ConfigParser()
        config_parser.read_string(config_string)
        return config_parser


def set_subject(
    message: EmailMessage, package: str, body: str, config_file: ConfigFile
) -> None:
    if config_file.package_type == "arch":
        if "Finished making: " in body:
            message["Subject"] = "BUILD SUCCESS: '{}'".format(package)
            print("BUILD SUCCESS")
        else:
            message["Subject"] = "BUILD FAILURE: '{}'".format(package)


def set_addresses(conf: ConfigFile, message: EmailMessage) -> None:
    message["From"] = conf.from_address
    message["To"] = conf.to_address


def get_pkgname() -> str:
    cwd = os.getcwd()
    return cwd[cwd.rfind("/") + 1 :]


def get_log_from_file(conf: ConfigFile) -> str:
    if conf.tail_value < 1:
        print("Error: tailvalue cannot be smaller than 1")
        sys.exit(1)

    try:
        with open(conf.log_file, "r", encoding="utf-8") as log_file_reader:
            log = log_file_reader.readlines()
    except (FileNotFoundError, PermissionError, IOError):
        print("Error: could not access log at '{}'".format(conf.log_file))
        sys.exit(1)

    log.reverse()

    tail_lines = []

    tail_index = 1

    for line in log:
        if tail_index == conf.tail_value:
            break
        tail_lines.append(line)
        tail_index += 1

    tail_lines.reverse()
    tail_lines[-1] = tail_lines[-1][:-1]

    mail_text = "".join(tail_lines)

    return mail_text


def send_email_via_smtp(conf: ConfigFile, message: EmailMessage) -> None:
    context = ssl.create_default_context()

    if conf.smtp_connection == "starttls":
        with smtplib.SMTP_SSL(conf.smtp_server, conf.smtp_port) as server:
            server.starttls(context=context)
            server.login(conf.from_address, conf.password)
            server.send_message(message)
    else:
        with smtplib.SMTP_SSL(
            conf.smtp_server, conf.smtp_port, context=context
        ) as server:
            server.login(conf.from_address, conf.password)
            server.send_message(message)


def main() -> None:
    config_file_path = os.path.join(
        get_xdg_dir("XDG_CONFIG_HOME", ".config"), "sendreportmail", "config"
    )
    config = ConfigFile(config_file_path)

    msg = EmailMessage()
    email_body = get_log_from_file(config)
    msg.set_content(email_body)

    pkgname = get_pkgname()

    set_subject(msg, pkgname, email_body, config)
    set_addresses(config, msg)

    send_email_via_smtp(config, msg)


if __name__ == "__main__":
    main()
