# Copyright 2018 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 that implement a web components page.

Summary of classes:
 WebComponentsPage: Show one web components page.
"""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import


import logging

import settings
from framework import flaskservlet
from framework import servlet
from framework import framework_helpers
from framework import permissions
from framework import urls


class WebComponentsPage(servlet.Servlet):

  _PAGE_TEMPLATE = 'tracker/web-components-page.ezt'

  def AssertBasePermission(self, mr):
    # type: (MonorailRequest) -> None
    """Check that the user has permission to visit this page."""
    super(WebComponentsPage, self).AssertBasePermission(mr)

  def GatherPageData(self, mr):
    # type: (MonorailRequest) -> Mapping[str, Any]
    """Build up a dictionary of data values to use when rendering the page.

    Args:
      mr: commonly used info parsed from the request.

    Returns:
      Dict of values used by EZT for rendering the page.
    """
    # Create link to view in old UI for the list view pages.
    old_ui_url = None
    url = mr.request.url
    if '/hotlists/' in url:
      hotlist = self.services.features.GetHotlist(mr.cnxn, mr.hotlist_id)
      if '/people' in url:
        old_ui_url = '/u/%s/hotlists/%s/people' % (
            hotlist.owner_ids[0], hotlist.name)
      elif '/settings' in url:
        old_ui_url = '/u/%s/hotlists/%s/details' % (
            hotlist.owner_ids[0], hotlist.name)
      else:
        old_ui_url = '/u/%s/hotlists/%s' % (hotlist.owner_ids[0], hotlist.name)

    return {
       'local_id': mr.local_id,
       'old_ui_url': old_ui_url,
      }

  # def GetWebComponentsIssueDetail(self, **kwargs):
  #   return self.handler(**kwargs)

  # def GetWebComponentsIssueList(self, **kwargs):
  #   return self.handler(**kwargs)

  # def GetWebComponentsIssueWizard(self, **kwargs):
  #   return self.handler(**kwargs)

  # def GetWebComponentsIssueNewEntry(self, **kwargs):
  #   return self.handler(**kwargs)


class ProjectListPage(WebComponentsPage):

  def GatherPageData(self, mr):
    # type: (MonorailRequest) -> Mapping[str, Any]
    """Build up a dictionary of data values to use when rendering the page.

    May redirect the user to a default project if one is configured for
    the current domain.

    Args:
      mr: commonly used info parsed from the request.

    Returns:
      Dict of values used by EZT for rendering the page.
    """
    redirect_msg = self._MaybeRedirectToDomainDefaultProject(mr)
    logging.info(redirect_msg)
    return {
        'local_id': None,
        'old_ui_url': '/hosting_old/',
    }

  def _MaybeRedirectToDomainDefaultProject(self, mr):
    # type: (MonorailRequest) -> str
    """If there is a relevant default project, redirect to it.

      This function is copied from: sitewide/hostinghome.py

      Args:
        mr: commonly used info parsed from the request.

      Returns:
        String with a message about what happened for logging purposes.
    """
    project_name = settings.domain_to_default_project.get(mr.request.host)
    if not project_name:
      return 'No configured default project redirect for this domain.'

    project = None
    try:
      project = self.services.project.GetProjectByName(mr.cnxn, project_name)
    except exceptions.NoSuchProjectException:
      pass

    if not project:
      return 'Domain default project %s not found' % project_name

    if not permissions.UserCanViewProject(mr.auth.user_pb,
                                          mr.auth.effective_ids, project):
      return 'User cannot view default project: %r' % project

    project_url = '/p/%s' % project_name
    self.redirect(project_url, abort=True)
    return 'Redirected to %r' % project_url
