# Copyright 2016 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Classes for user updates pages.

  AbstractUserUpdatesPage: Base class for all user updates pages
  UserUpdatesProjects: Handles displaying starred projects
  UserUpdatesDevelopers: Handles displaying starred developers
  UserUpdatesIndividual: Handles displaying activities by the viewed user
"""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import


import logging

import ezt

from businesslogic import work_env
from features import activities
from framework import servlet
from framework import urls


class AbstractUserUpdatesPage(servlet.Servlet):
  """Base class for user updates pages."""

  _PAGE_TEMPLATE = 'sitewide/user-updates-page.ezt'

  # Subclasses should override these constants.
  _UPDATES_PAGE_URL = None
  # What to highlight in the middle column on user updates pages - 'project',
  # 'user', or None
  _HIGHLIGHT = None
  # What the ending phrase for activity titles should be - 'by_user',
  # 'in_project', or None
  _ENDING = None
  _TAB_MODE = None

  def GatherPageData(self, mr):
    """Build up a dictionary of data values to use when rendering the page."""
    # TODO(jrobbins): re-implement
    # if self.CheckRevelationCaptcha(mr, mr.errors):
    #   mr.viewed_user_auth.user_view.RevealEmail()

    page_data = {
        'user_tab_mode': 'st5',
        'viewing_user_page': ezt.boolean(True),
        'user_updates_tab_mode': self._TAB_MODE,
        }

    user_ids = self._GetUserIDsForUpdates(mr)
    project_ids = self._GetProjectIDsForUpdates(mr)
    page_data.update(activities.GatherUpdatesData(
        self.services, mr, user_ids=user_ids,
        project_ids=project_ids, ending=self._ENDING,
        updates_page_url=self._UPDATES_PAGE_URL, highlight=self._HIGHLIGHT))

    return page_data

  def _GetUserIDsForUpdates(self, _mr):
    """Returns a list of user IDs to retrieve activities from."""
    return None  # Means any.

  def _GetProjectIDsForUpdates(self, _mr):
    """Returns a list of project IDs to retrieve activities from."""
    return None  # Means any.


class UserUpdatesProjects(AbstractUserUpdatesPage):
  """Shows a page of updates from projects starred by a user."""

  _UPDATES_FEED_URL = urls.USER_UPDATES_PROJECTS
  _UPDATES_PAGE_URL = urls.USER_UPDATES_PROJECTS
  _HIGHLIGHT = 'project'
  _ENDING = 'by_user'
  _TAB_MODE = 'st2'

  def _GetProjectIDsForUpdates(self, mr):
    """Returns a list of project IDs whom to retrieve activities from."""
    with work_env.WorkEnv(mr, self.services) as we:
      starred_projects = we.ListStarredProjects(
          viewed_user_id=mr.viewed_user_auth.user_id)
    return [project.project_id for project in starred_projects]

  def GetUserUpdatesProjectsPage(self, **kwargs):
    return self.handler(**kwargs)


class UserUpdatesDevelopers(AbstractUserUpdatesPage):
  """Shows a page of updates from developers starred by a user."""

  _UPDATES_FEED_URL = urls.USER_UPDATES_DEVELOPERS
  _UPDATES_PAGE_URL = urls.USER_UPDATES_DEVELOPERS
  _HIGHLIGHT = 'user'
  _ENDING = 'in_project'
  _TAB_MODE = 'st3'

  def _GetUserIDsForUpdates(self, mr):
    """Returns a list of user IDs whom to retrieve activities from."""
    user_ids = self.services.user_star.LookupStarredItemIDs(
        mr.cnxn, mr.viewed_user_auth.user_id)
    logging.debug('StarredUsers: %r', user_ids)
    return user_ids

  def GetUserUpdatesDevelopersPage(self, **kwargs):
    return self.handler(**kwargs)


class UserUpdatesIndividual(AbstractUserUpdatesPage):
  """Shows a page of updates initiated by a user."""

  _UPDATES_FEED_URL = urls.USER_UPDATES_MINE + '/user'
  _UPDATES_PAGE_URL = urls.USER_UPDATES_MINE
  _HIGHLIGHT = 'project'
  _TAB_MODE = 'st1'

  def _GetUserIDsForUpdates(self, mr):
    """Returns a list of user IDs whom to retrieve activities from."""
    return [mr.viewed_user_auth.user_id]

  def GetUserUpdatesPage(self, **kwargs):
    return self.handler(**kwargs)
