#       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.

from __future__ import unicode_literals
from __future__ import absolute_import
import logging

import pkg_resources
from datetime import datetime

import six
from formencode import validators
from tg import request
from tg import tmpl_context as c, app_globals as g
from pytz import timezone
from tg import expose, redirect, validate, flash
from tg.decorators import without_trailing_slash
from decorator import decorator
from webob import exc

from allura import version
from allura.app import Application, SitemapEntry
from allura.controllers import BaseController
from allura.controllers.feed import FeedArgs, FeedController
from allura.controllers.rest import AppRestControllerMixin
from allura.lib import helpers as h
from allura.lib.decorators import require_post
from allura.lib.plugin import AuthenticationProvider
from allura.lib.security import require_access
from allura.lib.widgets.user_profile import SendMessageForm, SectionsUtil, SectionBase, ProjectsSectionBase
from allura.model import User, ACE, ProjectRole

log = logging.getLogger(__name__)


class F(object):
    send_message = SendMessageForm()


class UserProfileApp(Application):

    """
    This is the Profile tool, which is automatically installed as
    the default (first) tool on any user project.
    """
    __version__ = version.__version__
    tool_label = 'Profile'
    max_instances = 0
    has_notifications = False
    icons = {
        24: 'images/home_24.png',
        32: 'images/home_32.png',
        48: 'images/home_48.png'
    }

    def __init__(self, user, config):
        Application.__init__(self, user, config)
        self.root = UserProfileController()
        self.templates = pkg_resources.resource_filename(
            'allura.ext.user_profile', 'templates')
        self.api_root = UserProfileRestController()

    @property
    @h.exceptionless([], log)
    def sitemap(self):
        return [SitemapEntry('Profile', '.')]

    def admin_menu(self):
        return []

    def main_menu(self):
        return [SitemapEntry('Profile', '.')]

    def is_visible_to(self, user):
        # we don't work with user subprojects
        return c.project.is_root

    def install(self, project):
        pr = ProjectRole.by_user(c.user)
        if pr:
            self.config.acl = [
                ACE.allow(pr._id, perm)
                for perm in self.permissions]

    def uninstall(self, project):  # pragma no cover
        pass

    @property
    def profile_sections(self):
        """
        Loads and caches user profile sections from the entry-point
        group ``[allura.user_profile.sections]``.

        Profile sections are loaded unless disabled (see
        `allura.lib.helpers.iter_entry_points`) and are sorted according
        to the `user_profile_sections.order` config value.

        The config should contain a comma-separated list of entry point names
        in the order that they should appear in the profile.  Unknown or
        disabled sections are ignored, and available sections that are not
        specified in the order come after all explicitly ordered sections,
        sorted randomly.
        """
        if hasattr(UserProfileApp, '_sections'):
            return UserProfileApp._sections
        UserProfileApp._sections = SectionsUtil.load_sections('user_profile')
        return UserProfileApp._sections


class UserProfileController(BaseController, FeedController):

    def _check_security(self):
        require_access(c.project, 'read')

    def _check_can_message(self, from_user, to_user):
        if from_user is User.anonymous():
            flash('You must be logged in to send user messages.', 'info')
            redirect(six.ensure_text(request.referer or '/'))

        if not (from_user and from_user.get_pref('email_address')):
            flash('In order to send messages, you must have an email address '
                  'associated with your account.', 'info')
            redirect(six.ensure_text(request.referer or '/'))

        if not (to_user and to_user.get_pref('email_address')):
            flash('This user can not receive messages because they do not have '
                  'an email address associated with their account.', 'info')
            redirect(six.ensure_text(request.referer or '/'))

        if to_user.get_pref('disable_user_messages'):
            flash('This user has disabled direct email messages', 'info')
            redirect(six.ensure_text(request.referer or '/'))

    @expose('jinja:allura.ext.user_profile:templates/user_index.html')
    def index(self, **kw):
        user = c.project.user_project_of
        if not user:
            raise exc.HTTPNotFound()
        provider = AuthenticationProvider.get(request)
        sections = [section(user, c.project)
                    for section in c.app.profile_sections]

        noindex = True
        for s in sections:
            s.setup_context()
            if s.context.get('projects') or s.context.get('timeline'):
                noindex = False
        return dict(
            user=user,
            reg_date=provider.user_registration_date(user),
            sections=sections,
            noindex=noindex,
        )

    def get_feed(self, project, app, user):
        """Return a :class:`allura.controllers.feed.FeedArgs` object describing
        the xml feed for this controller.

        Overrides :meth:`allura.controllers.feed.FeedController.get_feed`.

        """
        user = project.user_project_of
        return FeedArgs(
            {'author_link': user.url()},
            'Recent posts by %s' % user.display_name,
            project.url())

    @expose('jinja:allura.ext.user_profile:templates/send_message.html')
    def send_message(self):
        """Render form for sending a message to another user.

        """
        self._check_can_message(c.user, c.project.user_project_of)

        delay = c.user.time_to_next_user_message()
        expire_time = str(delay) if delay else None
        c.form = F.send_message
        if c.user.get_pref('message_reply_real_address'):
            c.form.fields.reply_to_real_address.attrs = {'checked': 'checked'}
        return dict(user=c.project.user_project_of, expire_time=expire_time)

    @require_post()
    @expose()
    @validate(dict(subject=validators.NotEmpty,
                   message=validators.NotEmpty))
    def send_user_message(self, subject='', message='', cc=None, reply_to_real_address=None):
        """Handle POST for sending a message to another user.

        """
        self._check_can_message(c.user, c.project.user_project_of)

        if cc:
            cc = c.user.get_pref('email_address')

        if c.user.can_send_user_message():
            if reply_to_real_address:
                c.user.set_pref('message_reply_real_address', True)
            c.user.send_user_message(
                c.project.user_project_of, subject, message, cc, reply_to_real_address, c.user.preferences.email_address)
            flash("Message sent.")
        else:
            flash("You can't send more than %i messages per %i seconds" % (
                g.user_message_max_messages,
                g.user_message_time_interval), 'error')
        return redirect(c.project.user_project_of.url())
        
    @without_trailing_slash
    @expose('jinja:allura.ext.user_profile:templates/user_card.html')
    def user_card(self):
        u = c.project.user_project_of
        locationData = u.get_pref('localization')
        webpages = u.get_pref('webpages')
        location = ''
        website = ''
        if locationData.city and locationData.country:
            location = locationData.city + ', ' + locationData.country
        elif locationData.country and not locationData.city:
            location = locationData.country
        elif locationData.city and not locationData.country:
            location = locationData.city

        if len(webpages) > 0:
            website = webpages[0]

        return dict(
            user=u,
            location=location,
            website=website)


class UserProfileRestController(AppRestControllerMixin):
    @expose('json:')
    def index(self, **kw):
        user = c.project.user_project_of
        if not user:
            raise exc.HTTPNotFound()
        sections = [section(user, c.project)
                    for section in c.app.profile_sections]
        json = {}
        for s in sections:
            if hasattr(s, '__json__'):
                json.update(s.__json__())
        return json


class ProfileSectionBase(SectionBase):

    """
    This is the base class for sections on the Profile tool.

    .. py:attribute:: template

       A resource string pointing to the template for this section.  E.g.::

           template = "allura.ext.user_profile:templates/projects.html"

    Sections must be pointed to by an entry-point in the group
    ``[allura.user_profile.sections]``.
    """

    def __init__(self, user, project):
        """
        Creates a section for the given :param:`user` and user
        :param:`project`.  Stores the values as attributes of
        the same name.
        """
        super(ProfileSectionBase, self).__init__(user)
        self.project = project


class PersonalDataSection(ProfileSectionBase):
    template = 'allura.ext.user_profile:templates/sections/personal-data.html'

    def prepare_context(self, context):
        context['timezone'] = self.user.get_pref('timezone')
        if context['timezone']:
            tz = timezone(context['timezone'])
            context['timezone'] = tz.tzname(datetime.utcnow())
        return context

    def __json__(self):
        auth_provider = AuthenticationProvider.get(request)
        return dict(
            username=self.user.username,
            name=self.user.display_name,
            joined=auth_provider.user_registration_date(self.user),
            localization=self.user.get_pref('localization')._deinstrument(),
            sex=self.user.get_pref('sex'),
            telnumbers=self.user.get_pref('telnumbers')._deinstrument(),
            skypeaccount=self.user.get_pref('skypeaccount'),
            webpages=self.user.get_pref('webpages')._deinstrument(),
            availability=self.user.get_pref('availability')._deinstrument())


class ProjectsSection(ProfileSectionBase, ProjectsSectionBase):
    template = 'allura.ext.user_profile:templates/sections/projects.html'


class SkillsSection(ProfileSectionBase):
    template = 'allura.ext.user_profile:templates/sections/skills.html'

    def __json__(self):
        return dict(skills=self.user.get_skills())


class ToolsSection(ProfileSectionBase):
    template = 'allura.ext.user_profile:templates/sections/tools.html'


class SocialSection(ProfileSectionBase):
    template = 'allura.ext.user_profile:templates/sections/social.html'

    def __json__(self):
        return dict(
            socialnetworks=self.user.get_pref('socialnetworks')._deinstrument())
