# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import datetime
import logging
import logging.handlers
import os
import socket
import time

import common

from autotest_lib.site_utils.rpm_control_system.config import rpm_config
from autotest_lib.site_utils import log_socket_server
from autotest_lib.site_utils.rpm_control_system import rpm_infrastructure_exception

LOGGING_FORMAT = rpm_config.get('GENERAL', 'logging_format')
RECEIVERS = rpm_config.get('RPM_INFRASTRUCTURE',
                           'email_notification_recipients').split(',')
SUBJECT_LINE = (rpm_config.get('GENERAL', 'email_subject_line_format') %
                socket.gethostname())


class SuspendableSMTPHandler(logging.handlers.SMTPHandler):
    """SMTPHandler that can have it's emails suspended."""
    _suspend_start_time = datetime.datetime.now()
    _suspend_time_hrs = 0


    def suspend_emails(self, hours):
        """Suspend email notifications.

        @param hours: How many hours to suspend email notifications.
        """
        self._suspend_start_time = datetime.datetime.now()
        self._suspend_time_hrs = int(hours, 0)


    def resume_emails(self):
        """Resume email notifications."""
        self._suspend_time_hrs = 0


    def emit(self, record):
        """Emit a log record.

        This subclassed version only emits the log record if emails are not
        suspended.

        @param record: Log record object we want to emit/record.
        """
        if datetime.datetime.now() < (self._suspend_start_time +
                datetime.timedelta(hours=self._suspend_time_hrs)):
            return
        record.msg += ('\n\nTo disable these emails use rpm_client from your '
                       'local checkout. For a 12 hour suspension run: '
                       'site_utils/rpm_control_system/rpm_client.py -d 12')
        return super(SuspendableSMTPHandler, self).emit(record)


def set_up_logging_to_file(log_dir, log_filename_format=None):
    """
    Correctly set up logging to have the correct format/level, log to a file,
    and send out email notifications in case of error level messages.

    @param log_dir: The directory in which log files should be created.
    @param log_filename_format: Format to use to create the log file.

    @returns email_handler: Logging handler used to send out email alerts.
    """
    logging.basicConfig(filename=_logfile_path(log_dir, log_filename_format),
                        level=logging.INFO, format=LOGGING_FORMAT)
    _set_common_logger_options()


def start_log_server(log_dir, log_filename_format):
    """Start log server to accept logging through a TCP server.

    @param log_dir: The directory in which log files should be created.
    @param log_filename_format: Format to use to create the log file.
    """
    log_filename = _logfile_path(log_dir, log_filename_format)
    log_socket_server.LogSocketServer.start(filename=log_filename,
                                            level=logging.INFO,
                                            format=LOGGING_FORMAT)


def set_up_logging_to_server():
    """Sets up logging option when using a logserver."""
    if log_socket_server.LogSocketServer.port is None:
        raise rpm_infrastructure_exception.RPMLoggingSetupError(
                'set_up_logging failed: Log server port is unknown.')
    socketHandler = logging.handlers.SocketHandler(
            'localhost', log_socket_server.LogSocketServer.port)
    logging.getLogger().addHandler(socketHandler)
    _set_common_logger_options()


def _logfile_path(log_dir, log_filename_format):
    """Get file name of log based on given log_filename_format.

    @param log_filename_format: Format to use to create the log file.
    """
    log_filename = time.strftime(log_filename_format)
    if not os.path.isdir(log_dir):
        os.makedirs(log_dir)
    return os.path.join(log_dir, log_filename)


def _set_common_logger_options():
    """Sets the options common to both file and server based logging."""
    logger = logging.getLogger()
    if rpm_config.getboolean('GENERAL', 'debug'):
        logger.setLevel(logging.DEBUG)
    email_handler = SuspendableSMTPHandler('localhost', 'rpm@google.com',
                                           RECEIVERS, SUBJECT_LINE, None)
    email_handler.setLevel(logging.ERROR)
    email_handler.setFormatter(logging.Formatter(LOGGING_FORMAT))
    logger.addHandler(email_handler)
