# -*- coding: utf-8 -*-
from trac.core import *
from trac.config import Option, BoolOption, Configuration
from trac.web.chrome import add_script,add_stylesheet,ITemplateProvider
from trac.web.main import IRequestHandler, IRequestFilter
from trac.web.api import ITemplateStreamFilter
from trac.util.html import Markup

from genshi.filters.transform import Transformer
from genshi.template import MarkupTemplate
from json.encoder import JSONEncoder
import re

class CompleteUserWeb(Component):
    implements(IRequestHandler, IRequestFilter, ITemplateProvider, ITemplateStreamFilter)

    single_fields = Option('complete-user','single_fields',['owner','reporter'], u"""単一ユーザを補完するフィールド設定します。""");
    composite_fields = Option('complete-user','composite_fields','cc', u"""複数ユーザを補完するフィールド設定します。""");
    name_check = BoolOption('complete-user','name_check', 'true', u"""ユーザを検索する際にNameが設定されているユーザのみを検索するかどうかを設定します。""");
    popup_delay = Option('complete-user','popup_delay','1.5',
                        u"""補完ウィンドウのポップアップ表示までの遅延時間を設定します。
                        
                        単位は秒で小数点も利用することができます
                        """)


    def filter_stream(self, req, method, filename, stream, data):
        if re.match(r'^/(ticket|newticket|admin|query)', req.path_info):
            single_fields = Configuration.getlist(self.config,"complete-user","single_fields",['owner','reporter']);
            composite_fields = Configuration.getlist(self.config,"complete-user","composite_fields","cc");
            popup_delay = Configuration.get(self.config,"complete-user","popup_delay","1.5");
            name_check = Configuration.getbool(self.config,"complete-user","name_check", "true");

            script = "<script type='text/javascript'>\n"
            script = script+"(function($){\n"
            script = script+"$(function(){\n"
#            script = script+"  ultimania.trac.POPUP_DELAY = " + popup_delay + ";\n"

            script = script+"  ultimania.trac.setAutoComplete('action_reassign_reassign_owner','" + req.base_path + "/completeuser',false);\n"
            script = script+"  ultimania.trac.setAutoComplete('gp_subject','" + req.base_path + "/completeuser',false);\n"
            script = script+"  ultimania.trac.setAutoComplete('sg_subject','" + req.base_path + "/completeuser',false);\n"
            script = script+"  ultimania.trac.setAutoComplete('bmod_value_owner','" + req.base_path + "/completeuser',false);\n"
            script = script+"  ultimania.trac.setAutoComplete('bmod_value_cc','" + req.base_path + "/completeuser',true);\n"
            for field in single_fields:
               script = script+"  ultimania.trac.setAutoComplete('field-" + field + "','" + req.base_path + "/completeuser',false);\n"
            for field in composite_fields:
               script = script+"  ultimania.trac.setAutoComplete('field-" + field + "','" + req.base_path + "/completeuser',true);\n"
            script = script+"})\n"
            script = script+"})(jQuery);\n"
            script = script+"</script>"
            return stream | Transformer('//div[@id="footer"]').before(MarkupTemplate(script).generate())
        else:
            return stream

    # IRequestFilter methods
    def pre_process_request(self, req, handler):
        return handler
        
    def post_process_request(self, req, template, content_type):
        return (template, content_type)

    def post_process_request(self, req, template, data, content_type):
        # jqueryのプラグインのインポートに変更
        if re.match(r'^/(ticket|newticket|admin|query)', req.path_info):
            add_stylesheet(req, 'completeuser/css/jquery.ui.all.css')
            add_stylesheet(req, 'completeuser/css/trac-completeuser.css')
            add_script(req, 'completeuser/js/jquery-ui-1.8.5.custom.min.js')
            add_script(req, 'completeuser/js/trac-completeuser.js')
        return (template, data, content_type)

    # IRequestHandler methods
    def match_request(self, req):
        if req.path_info in ('/login/completeuser', '/completeuser'):
            self.log.debug("%s matches %s" % (req.path_info, True))
            return True
        return False

    def process_request(self, req):
        name_check = Configuration.getbool(self.config,"complete-user","name_check", "True");
        query = req.args.get('term')
        self.log.info("query = "+query)
        db = self.env.get_db_cnx()
        cursor = db.cursor();
        join = ""
        where  = ""
        
        if name_check:
            join = "JOIN"
        else:
            join = "LEFT OUTER JOIN"
        if query != None:
            where  = ("AND (s.sid LIKE '%%%s%%' or sa.value LIKE '%%%s%%')") % (query,query)
        
        sql = ("SELECT s.sid, sa.value FROM session s %s session_attribute sa ON s.sid = sa.sid AND sa.name = 'name' WHERE s.authenticated = 1 %s") % (join,where)

        cursor.execute(sql)
        userlist = []
        for sid, value in cursor:
            userlist.append({"value":sid, "label": sid+"("+value+")"});
        self.log.info(userlist)
        response = JSONEncoder().encode(userlist).encode('utf-8')
        self.log.info(response)
#        response = simplejson.dumps({"UserList":userlist})
        self.log.debug("%s matches %s" % (req.path_info, True))

        req.send_response(200)
        req.send_header('Content-Type', 'application/json; charset=utf-8')
        req.send_header('Content-Length', len(response))

        req.end_headers()
        req.write(response)

    # ITemplateProvider methods
    def get_templates_dirs(self):
        return []

    def get_htdocs_dirs(self):
        from pkg_resources import resource_filename
        return [('completeuser', resource_filename(__name__, 'htdocs'))]
