# coding: utf-8

import json
import requests
from werkzeug.wrappers import BaseRequest
try:
    import gevent
except ImportError:
    gevent = None

HOMEPAGE = 'https://github.com/lepture/tower-slack'

TOWER_ICON = (
    'https://tower.im/assets/mobile/icon/'
    'icon@512-84fa5f6ced2a1bd53a409013f739b7ba.png'
)

MESSAGES = {
    'created': u'创建了',
    'updated': u'更新了',
    'deleted': u'删除了',
    'commented': u'评论了',

    'archived': u'归档了',
    'unarchived': u'激活了',

    'started': u'开始处理',
    'paused': u'暂停处理',
    'reopen': u'重新打开了',
    'completed': u'完成了',
    'deadline_changed': u'更新截止时间',

    'sticked': u'置顶了',
    'unsticked': u'取消置顶',

    'recovered': u'恢复了',

    # special
    'assigned': u'指派',
    'unassigned': u'取消指派',

    'docs': u'文档',
    'topics': u'讨论',
    'todos': u'任务',
    'todolists': u'任务清单',
    'attachments': u'文件',
}

COLORS = {
    'created': '#439FE0',
    'updated': 'warning',
    'completed': 'good',
    'deleted': 'danger',
}


class TowerSlack(object):
    def __init__(self, name='Tower', icon=TOWER_ICON, timeout=2):
        self.name = name
        self.icon = icon
        self.timeout = timeout

    def send_payload(self, payload, url, channel=None):
        if self.name:
            payload['username'] = self.name
        if self.icon:
            payload['icon_url'] = self.icon
        if channel:
            payload['channel'] = channel

        kwargs = dict(
            data=json.dumps(payload),
            headers={'Content-Type': 'application/json'},
            timeout=self.timeout,
        )

        if gevent:
            gevent.spawn(requests.post, url, **kwargs)
        else:
            requests.post(url, **kwargs)

    @staticmethod
    def create_payload(body, event):
        action = body['action']
        data = body['data']

        attachment = {}
        color = COLORS.get(action)
        if color:
            attachment['color'] = color

        project = data.pop('project')
        project_url = 'https://tower.im/projects/%s/' % project['guid']

        keys = data.keys()
        if len(keys) == 1:
            subject = data.pop(keys[0])
        else:
            subject = data.pop(event[:-1])
        subject_url = get_subject_url(project_url, event, subject['guid'])

        author = subject.get('handler')
        if author:
            attachment['author_name'] = author['nickname']
            author_link = 'https://tower.im/members/%s/' % (author['guid'])
            attachment['author_link'] = author_link

        action_text = u'%s%s' % (
            MESSAGES.get(action, action),
            MESSAGES.get(event, event),
        )

        text = u'<%s|#%s>: %s <%s|%s>' % (
            project_url, project['name'],
            action_text,
            subject_url, subject['title'],
        )
        if action in ['assigned', 'unassigned']:
            assignee = subject.get('assignee')
            if assignee:
                text = u'%s 给 %s' % (text, assignee['nickname'])

        content = subject.get('content')
        if content:
            text = u'%s \n> %s' % (text, content)

        attachment['text'] = text
        return {'attachments': [attachment]}

    def __call__(self, environ, start_response):
        req = BaseRequest(environ)

        if req.path == '/ip':
            return response(start_response, body=str(req.remote_addr))

        if req.method != 'POST':
            return redirect_homepage(start_response)

        event = req.headers.get('X-Tower-Event')
        if not event:
            return bad_request(start_response)

        signature = req.headers.get('X-Tower-Signature')
        if signature and signature[0] not in ('@', '#'):
            signature = None

        payload = self.create_payload(json.load(req.stream), event)
        url = 'https://hooks.slack.com/services/%s' % (req.path.lstrip('/'))
        self.send_payload(payload, url, signature)
        return response(start_response)


def get_subject_url(project_url, event, guid):
    if event == 'topics':
        # fix url for topics
        event = 'messages'
    return '%s%s/%s/' % (project_url, event, guid)


def response(start_response, code='200 OK', body='ok', headers=None):
    if headers is None:
        headers = []
    headers.extend([
        ('Content-Type', 'text/plain'),
        ('Content-Length', str(len(body))),
    ])
    start_response(code, headers)
    return [body]


def redirect_homepage(start_response):
    body = 'Redirect to %s' % HOMEPAGE
    headers = [('Location', HOMEPAGE)]
    code = '301 Moved Permanently'
    return response(start_response, code, body, headers)


def bad_request(start_response):
    return response(start_response, code='400 Bad Request', body='400')

@@ -2513,31 +2513,24 @@
 nk%0A%0A        
-action_
 text = u'%25s%25
@@ -2528,18 +2528,37 @@
 t = u'%25s
-%25s
+ %3C%25s%7C#%25s%3E %E7%9A%84%25s %3C%25s%7C%25s%3E
 ' %25 (%0A  
@@ -2601,102 +2601,8 @@
 n),%0A
-            MESSAGES.get(event, event),%0A        )%0A%0A        text = u'%3C%25s%7C#%25s%3E: %25s %3C%25s%7C%25s%3E' %25 (%0A
     
@@ -2655,19 +2655,34 @@
     
-action_text
+MESSAGES.get(event, event)
 ,%0A  
@@ -2883,18 +2883,22 @@
  u'%25s %E7%BB%99 
-%25s
+**%25s**
 ' %25 (tex
@@ -2937,31 +2937,28 @@
   co
-nt
+mm
 ent = 
-subject
+data
 .get('co
 nten
@@ -2953,18 +2953,18 @@
 .get('co
-nt
+mm
 ent')%0A  
@@ -2974,18 +2974,18 @@
    if co
-nt
+mm
 ent:%0A   
@@ -3004,17 +3004,16 @@
 t = u'%25s
- 
 %5Cn%3E %25s' 
@@ -3025,15 +3025,26 @@
 xt, 
+comment%5B'
 content
+'%5D
 )%0A%0A 
@@ -3076,16 +3076,59 @@
  = text%0A
+        attachment%5B'mrkdwn_in'%5D = %5B'text'%5D%0A
         

Format text with comment