# -*- coding: utf-8 -*-

#       Licensed to the Apache Software Foundation (ASF) under one
#       or more contributor license agreements.  See the NOTICE file
#       distributed with this work for additional information
#       regarding copyright ownership.  The ASF licenses this file
#       to you under the Apache License, Version 2.0 (the
#       "License"); you may not use this file except in compliance
#       with the License.  You may obtain a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#       Unless required by applicable law or agreed to in writing,
#       software distributed under the License is distributed on an
#       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
#       KIND, either express or implied.  See the License for the
#       specific language governing permissions and limitations
#       under the License.


"""The application's Globals object"""

__all__ = ['Globals']
import logging
import cgi
import json
import datetime
from urllib import urlencode
from subprocess import Popen, PIPE
import os
import traceback

import activitystream
import pkg_resources
import markdown
import pygments
import pygments.lexers
import pygments.formatters
import pygments.util
from tg import config, session
from pylons import request
from pylons import tmpl_context as c
from paste.deploy.converters import asbool, asint, aslist
from pypeline.markup import markup as pypeline_markup

import ew as ew_core
import ew.jinja2_ew as ew
from ming.utils import LazyProperty

import allura.tasks.event_tasks
from allura import model as M
from allura.lib.markdown_extensions import ForgeExtension
from allura.eventslistener import PostEvent

from allura.lib import gravatar, plugin, utils
from allura.lib import helpers as h
from allura.lib.widgets import analytics
from allura.lib.security import Credentials
from allura.lib.async import Connection, MockAMQ
from allura.lib.solr import MockSOLR, make_solr_from_config
from allura.lib.zarkov_helpers import ZarkovClient, zmq

log = logging.getLogger(__name__)


class ForgeMarkdown(markdown.Markdown):
    def convert(self, source):
        if len(source) > asint(config.get('markdown_render_max_length', 40000)):
            # if text is too big, markdown can take a long time to process it, so we return it as a plain text
            log.info('Text is too big. Skipping markdown processing')
            escaped = cgi.escape(h.really_unicode(source))
            return h.html.literal(u'<pre>%s</pre>' % escaped)
        try:
            return markdown.Markdown.convert(self, source)
        except Exception:
            log.info('Invalid markdown: %s  Upwards trace is %s', source,
                     ''.join(traceback.format_stack()), exc_info=True)
            escaped = h.really_unicode(source)
            escaped = cgi.escape(escaped)
            return h.html.literal(u"""<p><strong>ERROR!</strong> The markdown supplied could not be parsed correctly.
            Did you forget to surround a code snippet with "~~~~"?</p><pre>%s</pre>""" % escaped)


class Globals(object):
    """Container for objects available throughout the life of the application.

    One instance of Globals is created during application initialization and
    is available during requests via the 'app_globals' variable.

    """
    __shared_state = {}

    def __init__(self):
        self.__dict__ = self.__shared_state
        if self.__shared_state: return
        self.allura_templates = pkg_resources.resource_filename('allura', 'templates')

        # Setup SOLR
        self.solr_server = aslist(config.get('solr.server'), ',')
        # skip empty strings in case of extra commas
        self.solr_server = [s for s in self.solr_server if s]
        self.solr_query_server = config.get('solr.query_server')
        if asbool(config.get('solr.mock')):
            self.solr = self.solr_short_timeout = MockSOLR()
        elif self.solr_server:
            self.solr = make_solr_from_config(self.solr_server, self.solr_query_server)
            self.solr_short_timeout = make_solr_from_config(
                self.solr_server, self.solr_query_server,
                timeout=int(config.get('solr.short_timeout', 10)))
        else: # pragma no cover
            self.solr = None
            self.solr_short_timeout = None
        self.use_queue = asbool(config.get('use_queue', False))

        # Load login/logout urls; only used for SFX logins
        self.login_url = config.get('auth.login_url', '/auth/')
        self.logout_url = config.get('auth.logout_url', '/auth/logout')

        # Setup Gravatar
        self.gravatar = gravatar.url

        self.oid_store = M.OpenIdStore()

        # Setup pygments
        self.pygments_formatter = utils.LineAnchorCodeHtmlFormatter(
            cssclass='codehilite',
            linenos='table')

        # Setup Pypeline
        self.pypeline_markup = pypeline_markup

        # Setup analytics
        accounts = config.get('ga.account', 'UA-XXXXX-X')
        accounts = accounts.split(' ')
        self.analytics = analytics.GoogleAnalytics(accounts=accounts)

        self.icons = dict(
            admin=Icon('x', 'ico-admin'),
            pencil=Icon('p', 'ico-pencil'),
            help=Icon('h', 'ico-help'),
            search=Icon('s', 'ico-search'),
            history=Icon('N', 'ico-history'),
            feed=Icon('f', 'ico-feed'),
            mail=Icon('M', 'ico-mail'),
            reply=Icon('w', 'ico-reply'),
            tag=Icon('z', 'ico-tag'),
            flag=Icon('^', 'ico-flag'),
            undelete=Icon('+', 'ico-undelete'),
            delete=Icon('#', 'ico-delete'),
            close=Icon('D', 'ico-close'),
            table=Icon('n', 'ico-table'),
            stats=Icon('Y', 'ico-stats'),
            pin=Icon('@', 'ico-pin'),
            folder=Icon('o', 'ico-folder'),
            fork=Icon('R', 'ico-fork'),
            merge=Icon('J', 'ico-merge'),
            plus=Icon('+', 'ico-plus'),
            conversation=Icon('q', 'ico-conversation'),
            group=Icon('g', 'ico-group'),
            user=Icon('U', 'ico-user'),
            secure=Icon('(', 'ico-lock'),
            unsecure=Icon(')', 'ico-unlock'),
            star=Icon('S', 'ico-star'),
            watch=Icon('E', 'ico-watch'),
            # Permissions
            perm_read=Icon('E', 'ico-focus'),
            perm_update=Icon('0', 'ico-sync'),
            perm_create=Icon('e', 'ico-config'),
            perm_register=Icon('e', 'ico-config'),
            perm_delete=Icon('-', 'ico-minuscirc'),
            perm_tool=Icon('x', 'ico-config'),
            perm_admin=Icon('(', 'ico-lock'),
            perm_has_yes=Icon('3', 'ico-check'),
            perm_has_no=Icon('d', 'ico-noentry'),
            perm_has_inherit=Icon('2', 'ico-checkcircle'),
        )

        # Cache some loaded entry points
        def _cache_eps(section_name, dict_cls=dict):
            d = dict_cls()
            for ep in h.iter_entry_points(section_name):
                value = ep.load()
                d[ep.name] = value
            return d

        class entry_point_loading_dict(dict):
            def __missing__(self, key):
                self[key] = _cache_eps(key)
                return self[key]

        self.entry_points = entry_point_loading_dict(
            tool=_cache_eps('allura', dict_cls=utils.CaseInsensitiveDict),
            auth=_cache_eps('allura.auth'),
            registration=_cache_eps('allura.project_registration'),
            theme=_cache_eps('allura.theme'),
            user_prefs=_cache_eps('allura.user_prefs'),
            spam=_cache_eps('allura.spam'),
            stats=_cache_eps('allura.stats'),
            site_stats=_cache_eps('allura.site_stats'),
            admin=_cache_eps('allura.admin'),
            )

        # Zarkov logger
        self._zarkov = None

        # Set listeners to update stats
        statslisteners = []
        for name, ep in self.entry_points['stats'].iteritems():
            statslisteners.append(ep())
        self.statsUpdater = PostEvent(statslisteners)

        self.tmpdir = os.getenv('TMPDIR', '/tmp')

    @LazyProperty
    def spam_checker(self):
        """Return a SpamFilter implementation.
        """
        from allura.lib import spam
        return spam.SpamFilter.get(config, self.entry_points['spam'])

    @LazyProperty
    def director(self):
        """Return activitystream director"""
        if asbool(config.get('activitystream.recording.enabled', False)):
            return activitystream.director()
        else:
            class NullActivityStreamDirector(object):
                def connect(self, *a, **kw):
                    pass
                def disconnect(self, *a, **kw):
                    pass
                def is_connected(self, *a, **kw):
                    return False
                def create_activity(self, *a, **kw):
                    pass
                def get_timeline(self, *a, **kw):
                    return []
            return NullActivityStreamDirector()

    @LazyProperty
    def amq_conn(self):
        if asbool(config.get('amqp.enabled', 'true')):
            if asbool(config.get('amqp.mock')):
                return MockAMQ(self)
            else:
                return Connection(
                    hostname=config.get('amqp.hostname', 'localhost'),
                    port=asint(config.get('amqp.port', 5672)),
                    userid=config.get('amqp.userid', 'testuser'),
                    password=config.get('amqp.password', 'testpw'),
                    vhost=config.get('amqp.vhost', 'testvhost'))
        else:
            return None

    def post_event(self, topic, *args, **kwargs):
        allura.tasks.event_tasks.event.post(topic, *args, **kwargs)

    def zarkov_event(
        self, event_type,
        user=None, neighborhood=None, project=None, app=None,
        extra=None):
        context = dict(
            user=None,
            neighborhood=None, project=None, tool=None,
            mount_point=None,
            is_project_member=False)

        if not zmq:
            return

        user = user or getattr(c, 'user', None)
        project = project or getattr(c, 'project', None)
        app = app or getattr(c, 'app', None)
        if user: context['user'] = user.username
        if project:
            context.update(
                project=project.shortname,
                neighborhood=project.neighborhood.url_prefix.strip('/'))
            if user:
                cred = Credentials.get()
                if cred is not None:
                    for pr in cred.user_roles(user._id, project._id).reaching_roles:
                        if pr.get('name') and pr.get('name')[0] != '*':
                            context['is_project_member'] = True
        if app:
            context.update(
                tool=app.config.tool_name,
                mount_point=app.config.options.mount_point)

        try:
            if self._zarkov is None:
                self._zarkov = ZarkovClient(
                    config.get('zarkov.host', 'tcp://127.0.0.1:6543'))
            self._zarkov.event(event_type, context, extra)
        except Exception, ex:
            self._zarkov = None
            log.error('Error sending zarkov event(%r): %r', ex, dict(
                    type=event_type, context=context, extra=extra))

    @LazyProperty
    def theme(self):
        return plugin.ThemeProvider.get()

    @property
    def antispam(self):
        a = request.environ.get('allura.antispam')
        if a is None:
            a = request.environ['allura.antispam'] = utils.AntiSpam()
        return a

    @property
    def credentials(self):
        return Credentials.get()

    def handle_paging(self, limit, page, default=50):
        limit = self.manage_paging_preference(limit, default)
        page = max(int(page), 0)
        start = page * int(limit)
        return (limit, page, start)

    def manage_paging_preference(self, limit, default=50):
        if limit:
            if c.user in (None, M.User.anonymous()):
                session['results_per_page'] = int(limit)
                session.save()
            else:
                c.user.set_pref('results_per_page', int(limit))
        else:
            if c.user in (None, M.User.anonymous()):
                try:
                    limit = session['results_per_page']
                except (KeyError, TypeError):  # TypeError if no session registered for thread
                    limit = default
            else:
                limit = c.user.get_pref('results_per_page') or default
        return limit

    def document_class(self, neighborhood):
        classes = ''
        if neighborhood:
            classes += ' neighborhood-%s' % neighborhood.name
        if not neighborhood and c.project:
            classes += ' neighborhood-%s' % c.project.neighborhood.name
        if c.project:
            classes += ' project-%s' % c.project.shortname
        if c.app:
            classes += ' mountpoint-%s' % c.app.config.options.mount_point
        return classes

    def highlight(self, text, lexer=None, filename=None):
        if not text:
            return h.html.literal('<em>Empty file</em>')
        # Don't use line numbers for diff highlight's, as per [#1484]
        if lexer == 'diff':
            formatter = pygments.formatters.HtmlFormatter(cssclass='codehilite', linenos=False)
        else:
            formatter = self.pygments_formatter
        if lexer is None:
            try:
                lexer = pygments.lexers.get_lexer_for_filename(filename, encoding='chardet')
            except pygments.util.ClassNotFound:
                # no highlighting, but we should escape, encode, and wrap it in a <pre>
                text = h.really_unicode(text)
                text = cgi.escape(text)
                return h.html.literal(u'<pre>' + text + u'</pre>')
        else:
            lexer = pygments.lexers.get_lexer_by_name(lexer, encoding='chardet')
        return h.html.literal(pygments.highlight(text, lexer, formatter))

    def forge_markdown(self, **kwargs):
        '''return a markdown.Markdown object on which you can call convert'''
        return ForgeMarkdown(
                extensions=['codehilite', ForgeExtension(**kwargs), 'tables', 'toc', 'nl2br'], # 'fenced_code'
                output_format='html4')

    @property
    def markdown(self):
        return self.forge_markdown()

    @property
    def markdown_wiki(self):
        if c.project.is_nbhd_project:
            return self.forge_markdown(wiki=True, macro_context='neighborhood-wiki')
        elif c.project.is_user_project:
            return self.forge_markdown(wiki=True, macro_context='userproject-wiki')
        else:
            return self.forge_markdown(wiki=True)

    @property
    def production_mode(self):
        return asbool(config.get('debug')) == False

    @LazyProperty
    def server_name(self):
        p1 = Popen(['hostname', '-s'], stdout=PIPE)
        server_name = p1.communicate()[0].strip()
        p1.wait()
        return server_name

    @property
    def resource_manager(self):
        return ew_core.widget_context.resource_manager

    def register_forge_css(self, href, **kw):
        self.resource_manager.register(ew.CSSLink('allura/' + href, **kw))

    def register_forge_js(self, href, **kw):
        self.resource_manager.register(ew.JSLink('allura/' + href, **kw))

    def register_app_css(self, href, **kw):
        app = kw.pop('app', c.app)
        self.resource_manager.register(
            ew.CSSLink('tool/%s/%s' % (app.config.tool_name.lower(), href), **kw))

    def register_app_js(self, href, **kw):
        app = kw.pop('app', c.app)
        self.resource_manager.register(
            ew.JSLink('tool/%s/%s' % (app.config.tool_name.lower(), href), **kw))

    def register_theme_css(self, href, **kw):
        self.resource_manager.register(ew.CSSLink(self.theme_href(href), **kw))

    def register_theme_js(self, href, **kw):
        self.resource_manager.register(ew.JSLink(self.theme_href(href), **kw))

    def register_js_snippet(self, text, **kw):
        self.resource_manager.register(ew.JSScript(text, **kw))

    def theme_href(self, href):
        theme_name = config.get('theme', 'allura')
        return self.resource_manager.absurl(
            'theme/%s/%s' % (theme_name, href))

    def oid_session(self):
        if 'openid_info' in session:
            return session['openid_info']
        else:
            session['openid_info'] = result = {}
            session.save()
            return result

    def forge_static(self, resource):
        base = config['static.url_base']
        if base.startswith(':'):
            base = request.scheme + base
        return base + resource

    def app_static(self, resource, app=None):
        base = config['static.url_base']
        app = app or c.app
        if base.startswith(':'):
            base = request.scheme + base
        return (base + app.config.tool_name.lower() + '/' + resource)

    def set_project(self, pid_or_project):
        'h.set_context() is preferred over this method'
        if isinstance(pid_or_project, M.Project):
            c.project = pid_or_project
        elif isinstance(pid_or_project, basestring):
            raise TypeError('need a Project instance, got %r' % pid_or_project)
        elif pid_or_project is None:
            c.project = None
        else:
            c.project = None
            log.error('Trying g.set_project(%r)', pid_or_project)

    def set_app(self, name):
        'h.set_context() is preferred over this method'
        c.app = c.project.app_instance(name)

    def url(self, base, **kw):
        params = urlencode(kw)
        if params:
            return '%s://%s%s?%s' % (request.scheme, request.host, base, params)
        else:
            return '%s://%s%s' % (request.scheme, request.host, base)

    def postload_contents(self):
        text = '''
'''
        return json.dumps(dict(text=text))

    def year(self):
        return datetime.datetime.utcnow().year

class Icon(object):
    def __init__(self, char, css):
        self.char = char
        self.css = css

def connect_amqp(config):
    return
