#       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)
            else:
                c.user.set_pref('message_reply_real_address', False)
            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())
