# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd

"""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 flaskservlet
from framework import urls
from sitewide import sitewide_helpers


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)
