#!/usr/bin/python
# -*- coding: utf8 -*-
# -*- Mode: Python; py-indent-offset: 4 -*-
# pylint: disable=C0103

""" Generator of daily report by e-mail. """

# This script take an e-mail and a password in parameter and then read DB

# Todo
# ====
# 
# daily-report pierreleray64@gmail.com phase.test.email phaseTEST2014 -l log/conf


import smtplib
import argparse
from datetime import datetime, timedelta
import logging
import logging.config
from pymongo import MongoClient

CLIENT = MongoClient('localhost', 27017)
DB = CLIENT.phase
ERRORS_COLLECTION = DB.errors
SERIES_COLLECTION = DB.series

DEFAULT_LOG_FILE = "/opt/phase/phase.conf"
LOGGER = logging.getLogger("phase")


def argument_parser():
    """Method that parse arguments from command line, return an error in
    case of missing parameter or return arguments with their value.

    :returns: dict -- Dict containing arguments.

    """
    # Get command line arguments
    parser = argparse.ArgumentParser()
    # Define expected arguments
    parser.add_argument("target",
        help="E-mail adress of the persone that will receive the message")
    parser.add_argument("username",
                        help="Username of the gmail account")
    parser.add_argument("password", help="Password of the gmail account")
    parser.add_argument("-l", "--log-conf", help="path to log configuration")
    # Return list of argument passed in command line
    return parser.parse_args()


def collect_series_information():
    """This method collect information from database and return it as a dict.

    :returns: dict -- Dict containing series informations.

    """
    today_date = datetime.utcnow().replace(
        hour=0, minute=0, second=0, microsecond=0)
    yesterday_date = today_date + timedelta(days=-1)
    start_date = "%sZ" % yesterday_date.isoformat()
    end_date = "%sZ" % today_date.isoformat()
    
    total_db_size = SERIES_COLLECTION.count()
    series_number = SERIES_COLLECTION.find(
        {"date": {"$gte": start_date, "$lt": end_date}}).count()
    errors_number = ERRORS_COLLECTION.find(
        {"date": {"$gte": start_date, "$lt": end_date}}).count()

    return {
        "totalDBSize": total_db_size,
        "seriesNumber": series_number,
        "errorNumber": errors_number
    }


def format_message(series_information):
    """This method take information from database and format it in according
    template

    :param series_information: Dict containing series informations.
    :type series_information: str.

    :returns: string -- E-mail subject and HTML string containing formatting
    series informations.
    """
    today_date = datetime.utcnow().strftime("%d-%m-%Y")
    subject = "[Phase] Daily report of %s" % today_date
    
    db_str = "Your db contains <b>%s</b> elements. <br/>"
    s_str = "Today, your Current Cost emit <b>%s</b>"
    s_str += " series on 43200 possible.<br/>"
    error_str = "Today, your Current Cost emit <b>%s</b> errors.<br/><br/>"

    body = "Hello, <br/><br/>"
    body += "Here is your phase daily report.<br/>"
    body += db_str % series_information["totalDBSize"]
    body += s_str % series_information["seriesNumber"]
    body += error_str % series_information["errorNumber"]
    body += "Thank you for your time."
    body = "" + body + ""

    return subject, body


def send_email(options):
    """This method send e-mail"""
    
    headers = ["From: %s" % options["target"],
               "Subject: %s" % options["subject"],
               "To: %s" % options["target"],
               "MIME-Version: 1.0",
               "Content-Type: text/html"]
    headers = "\r\n".join(headers)

    message = "%s\r\n\r\n%s" % (headers, options["body"])
    
    smtp_url = "smtp.gmail.com:587"
    
    log_message = "\n%s" % message
    LOGGER.error(log_message)

    server = smtplib.SMTP(smtp_url)
    server.starttls()
    server.login(options["username"], options["password"])
    server.sendmail(options["target"], options["target"], message)
    server.quit()


def main():
    """Main method that start phase process
    """
    # Parse command line argument and format it into according variable
    args = argument_parser()
    username = args.username
    password = args.password
    target = args.target
    log_conf = args.log_conf
    # Init logging file
    if log_conf is None:
        log_conf = DEFAULT_LOG_FILE
    logging.config.fileConfig(log_conf)

    series_information = collect_series_information()

    subject, body = format_message(series_information)

    options = {
        "username": username,
        "password": password,
        "target": target,
        "subject": subject,
        "body": body
    }
     
    send_email(options) 
    

if __name__ == '__main__':
    # Launch main method
    main()
