# Copyright 2015 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.

"""Provides an endpoint and web interface for associating alerts with bug."""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import re

from google.appengine.api import users
from google.appengine.ext import ndb

from dashboard import oauth2_decorator
from dashboard.common import request_handler
from dashboard.common import utils
from dashboard.models import anomaly
from dashboard.services import issue_tracker_service


class AssociateAlertsHandler(request_handler.RequestHandler):
  """Associates alerts with a bug."""

  def post(self):
    """POST is the same as GET for this endpoint."""
    self.get()

  @oauth2_decorator.DECORATOR.oauth_required
  def get(self):
    """Response handler for the page used to group an alert with a bug.

    Request parameters:
      bug_id: Bug ID number, as a string (when submitting the form).
      keys: Comma-separated alert keys in urlsafe format.
      confirm: If non-empty, associate alerts with a bug ID even if
          it appears that the alerts already associated with that bug
          have a non-overlapping revision range.

    Outputs:
      HTML with result.
    """
    if not utils.IsValidSheriffUser():
      user = users.get_current_user()
      self.ReportError('User "%s" not authorized.' % user, status=403)
      return

    urlsafe_keys = self.request.get('keys')
    if not urlsafe_keys:
      self.RenderHtml('bug_result.html', {
          'error': 'No alerts specified to add bugs to.'})
      return

    is_confirmed = bool(self.request.get('confirm'))
    bug_id = self.request.get('bug_id')
    if bug_id:
      self._AssociateAlertsWithBug(bug_id, urlsafe_keys, is_confirmed)
    else:
      self._ShowCommentDialog(urlsafe_keys)

  def _ShowCommentDialog(self, urlsafe_keys):
    """Sends a HTML page with a form for selecting a bug number.

    Args:
      urlsafe_keys: Comma-separated Alert keys in urlsafe format.
    """
    # Get information about Alert entities and related TestMetadata entities,
    # so that they can be compared with recent bugs.
    alert_keys = [ndb.Key(urlsafe=k) for k in urlsafe_keys.split(',')]
    alert_entities = ndb.get_multi(alert_keys)
    ranges = [(a.start_revision, a.end_revision) for a in alert_entities]

    # Mark bugs that have overlapping revision ranges as potentially relevant.
    # On the alerts page, alerts are only highlighted if the revision range
    # overlaps with the revision ranges for all of the selected alerts; the
    # same thing is done here.
    bugs = self._FetchBugs()
    for bug in bugs:
      this_range = _RevisionRangeFromSummary(bug['summary'])
      bug['relevant'] = all(_RangesOverlap(this_range, r) for r in ranges)

    self.RenderHtml('bug_result.html', {