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

"""A servlet for project owners to edit/delete a template"""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import time

import ezt

from framework import framework_helpers
from framework import framework_views
from framework import permissions
from framework import servlet
from framework import urls
from tracker import field_helpers
from tracker import template_helpers
from tracker import tracker_bizobj
from tracker import tracker_views
from mrproto import tracker_pb2


class TemplateDetail(servlet.Servlet):
  """Servlet allowing project owners to edit/delete an issue template"""

  _MAIN_TAB_MODE = servlet.Servlet.MAIN_TAB_PROCESS
  _PAGE_TEMPLATE = 'tracker/template-detail-page.ezt'
  _PROCESS_SUBTAB = servlet.Servlet.PROCESS_TAB_TEMPLATES

  def AssertBasePermission(self, mr):
    """Check whether the user has any permission to visit this page.

    Args:
      mr: commonly used info parsed from the request.
    """
    super(TemplateDetail, self).AssertBasePermission(mr)
    template = self.services.template.GetTemplateByName(mr.cnxn,
        mr.template_name, mr.project_id)

    if template:
      allow_view = permissions.CanViewTemplate(
          mr.auth.effective_ids, mr.perms, mr.project, template)
      if not allow_view:
        raise permissions.PermissionException(
            'User is not allowed to view this issue template')
    else:
      self.abort(404, 'issue template not found %s' % mr.template_name)

  def GatherPageData(self, mr):
    """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.
    """

    config = self.services.config.GetProjectConfig(mr.cnxn, mr.project_id)
    template = self.services.template.GetTemplateByName(mr.cnxn,
        mr.template_name, mr.project_id)
    template_view = tracker_views.IssueTemplateView(
        mr, template, self.services.user, config)
    with mr.profiler.Phase('making user views'):
      users_involved = tracker_bizobj.UsersInvolvedInTemplate(template)
      users_by_id = framework_views.MakeAllUserViews(
          mr.cnxn, self.services.user, users_involved)
      framework_views.RevealAllEmailsToMembers(
          mr.cnxn, self.services, mr.auth, users_by_id, mr.project)
    field_name_set = {fd.field_name.lower() for fd in config.field_defs
                      if fd.field_type == tracker_pb2.FieldTypes.ENUM_TYPE and
                      not fd.is_deleted}
    non_masked_labels = tracker_bizobj.NonMaskedLabels(
        template.labels, field_name_set)

    field_views = tracker_views.MakeAllFieldValueViews(
        config, template.labels, [], template.field_values, users_by_id,
        phases=template.phases)
    uneditable_fields = ezt.boolean(False)
    for fv in field_views:
      if permissions.CanEditValueForFieldDef(
          mr.auth.effective_ids, mr.perms, mr.project, fv.field_def.field_def):
        fv.is_editable = ezt.boolean(True)
      else:
        fv.is_editable = ezt.boolean(False)
        uneditable_fields = ezt.boolean(True)

    (prechecked_approvals, required_approval_ids,
     initial_phases) = template_helpers.GatherApprovalsPageData(
         template.approval_values, template.phases, config)

    allow_edit = permissions.CanEditTemplate(
        mr.auth.effective_ids, mr.perms, mr.project, template)

    return {
        'admin_tab_mode':
            self._PROCESS_SUBTAB,
        'allow_edit':
            ezt.boolean(allow_edit),
        'uneditable_fields':
            uneditable_fields,
        'new_template_form':
            ezt.boolean(False),
        'initial_members_only':
            template_view.members_only,
        'template_name':
            template_view.name,
        'initial_summary':
            template_view.summary,
        'initial_must_edit_summary':
            template_view.summary_must_be_edited,
        'initial_content':
            template_view.content,
        'initial_status':
            template_view.status,
        'initial_owner':
            template_view.ownername,
        'initial_owner_defaults_to_member':
            template_view.owner_defaults_to_member,
        'initial_components':
            template_view.components,
        'initial_component_required':
            template_view.component_required,
        'fields':
            [
                view for view in field_views
                if view.field_def.type_name != 'APPROVAL_TYPE'
            ],
        'initial_add_approvals':
            ezt.boolean(prechecked_approvals),
        'initial_phases':
            initial_phases,
        'approvals':
            [
                view for view in field_views
                if view.field_def.type_name == 'APPROVAL_TYPE'
            ],
        'prechecked_approvals':
            prechecked_approvals,
        'required_approval_ids':
            required_approval_ids,
        'labels':
            non_masked_labels,
        'initial_admins':
            template_view.admin_names,
    }

  def ProcessFormData(self, mr, post_data):
    """Validate and store the contents of the issues tracker admin page.

    Args:
      mr: commonly used info parsed from the request.
      post_data: HTML form data from the request.

    Returns:
      String URL to redirect the user to, or None if response was already sent.
    """

    config = self.services.config.GetProjectConfig(mr.cnxn, mr.project_id)
    parsed = template_helpers.ParseTemplateRequest(post_data, config)
    field_helpers.ShiftEnumFieldsIntoLabels(
        parsed.labels, [], parsed.field_val_strs, [], config)
    template = self.services.template.GetTemplateByName(mr.cnxn,
        parsed.name, mr.project_id)
    allow_edit = permissions.CanEditTemplate(
        mr.auth.effective_ids, mr.perms, mr.project, template)
    if not allow_edit:
      raise permissions.PermissionException(
          'User is not allowed edit this issue template.')

    if 'deletetemplate' in post_data:
      self.services.template.DeleteIssueTemplateDef(
          mr.cnxn, mr.project_id, template.template_id)
      return framework_helpers.FormatAbsoluteURL(
          mr, urls.ADMIN_TEMPLATES, deleted=1, ts=int(time.time()))

    (admin_ids, owner_id, component_ids,
     field_values, phases,
     approvals) = template_helpers.GetTemplateInfoFromParsed(
         mr, self.services, parsed, config)

    labels = [label for label in parsed.labels if label]
    field_helpers.AssertCustomFieldsEditPerms(
        mr, config, field_values, [], [], labels, [])
    field_helpers.ApplyRestrictedDefaultValues(
        mr, config, field_values, labels, template.field_values,
        template.labels)

    if mr.errors.AnyErrors():
      field_views = tracker_views.MakeAllFieldValueViews(
          config, [], [], field_values, {})

      prechecked_approvals = template_helpers.GetCheckedApprovalsFromParsed(
          parsed.approvals_to_phase_idx)

      self.PleaseCorrect(
          mr,
          initial_members_only=ezt.boolean(parsed.members_only),
          template_name=parsed.name,
          initial_summary=parsed.summary,
          initial_must_edit_summary=ezt.boolean(parsed.summary_must_be_edited),
          initial_content=parsed.content,
          initial_status=parsed.status,
          initial_owner=parsed.owner_str,
          initial_owner_defaults_to_member=ezt.boolean(
              parsed.owner_defaults_to_member),
          initial_components=', '.join(parsed.component_paths),
          initial_component_required=ezt.boolean(parsed.component_required),
          initial_admins=parsed.admin_str,
          labels=parsed.labels,
          fields=[view for view in field_views
                  if view.field_def.type_name != 'APPROVAL_TYPE'],
          initial_add_approvals=ezt.boolean(parsed.add_approvals),
          initial_phases=[tracker_pb2.Phase(name=name) for name in
                          parsed.phase_names],
          approvals=[view for view in field_views
                     if view.field_def.type_name == 'APPROVAL_TYPE'],
          prechecked_approvals=prechecked_approvals,
          required_approval_ids=parsed.required_approval_ids
      )
      return

    self.services.template.UpdateIssueTemplateDef(
        mr.cnxn, mr.project_id, template.template_id, name=parsed.name,
        content=parsed.content, summary=parsed.summary,
        summary_must_be_edited=parsed.summary_must_be_edited,
        status=parsed.status, members_only=parsed.members_only,
        owner_defaults_to_member=parsed.owner_defaults_to_member,
        component_required=parsed.component_required, owner_id=owner_id,
        labels=labels, component_ids=component_ids, admin_ids=admin_ids,
        field_values=field_values, phases=phases, approval_values=approvals)

    return framework_helpers.FormatAbsoluteURL(
        mr, urls.TEMPLATE_DETAIL, template=template.name,
        saved=1, ts=int(time.time()))

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

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