# -*- coding: utf-8 -*-
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import json
import logging
import requests
import smtplib
from time import sleep, strftime
from robot import CONFIG, SECRET

logger = logging.getLogger(__name__)


def is_stopped(issue):
    if hasattr(issue, 'resolution'):
        if getattr(issue.resolution, 'key', None) == 'fixed':
            logger.debug('%s: resolution is fixed', issue.key)
            return True

    elif issue.status.key in ['closed', 'resolved']:
        logger.debug('%s: status is closed or resolved', issue.key)
        return True

    logger.debug('%s: is_stopped == False', issue.key)
    return False


def notify(debug, issue, about, to=('%s@yandex-team.ru' % CONFIG['owner'], 'leroy@yandex-team.ru'), **kwargs):
    if not debug:
        send_mail(to=to, subject=CONFIG['MAILS'][about]['subj'].format(**kwargs),
                  message=CONFIG['MAILS'][about]['text'].format(**kwargs))

        followers = [follower.login for follower in issue.followers]
        if CONFIG['owner'] not in followers:
            logger.debug('%s: update followers', issue.key)
            issue.update(followers=followers + [CONFIG['owner']])


def send_mail(to, subject, message,
              from_='%s@yandex-team.ru' % SECRET['PASSPORT']['login'], password=SECRET['PASSPORT']['password']):
    try:
        for i in range(4):
            msg = MIMEMultipart('alternative')
            text = MIMEText(message, 'html', 'utf8')

            msg['From'] = from_
            msg['To'] = ', '.join(to)
            msg['Subject'] = subject
            msg.attach(text)

            conn = smtplib.SMTP_SSL('smtp.yandex-team.ru', 465)
            conn.set_debuglevel(False)
            conn.login(from_, password)

            try:
                conn.sendmail(from_, to, msg.as_string())
            finally:
                conn.close()
            break
    except:
        pass

def get_from_date(days_=2):
    return datetime.now() - relativedelta(days=days_)


def parse_st_datetime(date, local_tz=strftime('%z')):
    st_datetime, st_tz = date[:-5], date[-5:]

    st_datetime = datetime.strptime(st_datetime, '%Y-%m-%dT%H:%M:%S.%f')

    st_datetime = correct_tz(st_datetime, st_tz)
    st_datetime = correct_tz(st_datetime, local_tz)

    return st_datetime


def correct_tz(date, tz):
    tz_hours, tz_minutes = int(tz[-4:-2]), int(tz[-2:])
    if tz[0] == '+':
        return date + timedelta(hours=tz_hours, minutes=tz_minutes)
    else:
        return date - timedelta(hours=tz_hours, minutes=tz_minutes)


def restartable(retries=10, pause=60):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for try_ in xrange(retries):
                try:
                    return func(*args, **kwargs)
                except KeyboardInterrupt as kb_exception:
                    raise kb_exception
                except Exception as exc:
                    logger.warning('An exception occurred at attempt #{}\n{}\nRestarting in {} seconds...'.format(
                        try_, exc.message, pause))
                    sleep(pause)
                    continue
            raise Exception('Max retries has been reached ({})'.format(retries))
        return wrapper
    return decorator


@restartable(retries=3, pause=5)
def make_request(**kwargs):
    request = requests.post(**kwargs)
    if request.status_code != 200:
        raise Exception('request.status_code != 200\n{}'.format(request.text))
    return json.loads(request.content)
