# 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 the web interface for filing a bug on the issue tracker."""

import json
import logging

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

from dashboard import auto_bisect
from dashboard import issue_tracker_service
from dashboard import oauth2_decorator
from dashboard import request_handler
from dashboard import utils
from dashboard.models import alert
from dashboard.models import bug_data
from dashboard.models import bug_label_patterns

# A list of bug labels to suggest for all performance regression bugs.
_DEFAULT_LABELS = [
    'Type-Bug-Regression',
    'Pri-2',
    'Performance-Sheriff'
]
_OMAHA_PROXY_URL = 'https://omahaproxy.appspot.com/all.json'


class FileBugHandler(request_handler.RequestHandler):
  """Uses oauth2 to file a new bug with a set of alerts."""

  def post(self):
    """Make all the functions available via POST as well as GET."""
    self.get()

  @oauth2_decorator.decorator.oauth_required
  def get(self):
    """Either shows the form to file a bug, or if filled in, files the bug.

    The form to file a bug is popped up from the triage-dialog polymer element.
    The default summary, description and label strings are constructed there.

    Request parameters:
      summary: Bug summary string.
      description: Bug full description string.
      owner: Bug owner email address.
      keys: Comma-separated Alert keys in urlsafe format.

    Outputs:
      HTML, using the template 'bug_result.html'.
    """
    if not utils.IsValidSheriffUser():
      user = users.get_current_user()
      self.ReportError('User "%s" not authorized.' % user, status=403)
      return

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

    if self.request.get('finish'):
      self._CreateBug(summary, description, labels, keys)
    else:
      self._ShowBugDialog(summary, description, keys)

  def _ShowBugDialog(self, summary, description, urlsafe_keys):
    """Sends a HTML page with a form for filing the bug.

    Args:
      summary: The default bug summary string.
      description: The default bug description string.
      urlsafe_keys: Comma-separated Alert keys in urlsafe format.
    """
    # Fill in the owner field with the logged in user's email. For convenience,
    # if it's a @google.com account, swap @google.com with @chromium.org.
    user_email = users.get_current_user().email()
    if user_email.endswith('@google.com'):
      user_email = user_email.replace('@google.com', '@chromium.org')
    alert_keys = [ndb.Key(urlsafe=k) for k in urlsafe_keys.split(',')]
    labels = _FetchLabels(alert_keys)
    self.RenderHtml('bug_result.html', {
        'bug_create_form': True,
        'keys': urlsafe_keys,
        'summary': summary,
        'description': description,
        'labels': labels,
        'owner': user_email,
    })

  def _CreateBug(self, summary, description, labels, urlsafe_keys):
    """Creates a bug, associates it with the alerts, sends a HTML response.

    Args:
      summary: The new bug summary string.
      description: The new bug description string.
      labels: List of label strings for the new bug.
      urlsafe_keys: Comma-separated alert keys in urlsafe format.
    """
    alert_keys = [ndb.Key(urlsafe=k) for k in urlsafe_keys.split(',')]
    alerts = ndb.get_multi(alert_keys)

    if not description:
      description = 'See the link to graphs below.'

    milestone_label = _MilestoneLabel(alerts)
    if milestone_label:
      labels.append(milestone_label)

    # Only project members (@chromium.org accounts) can be owners of bugs.
    owner = self.request.get('owner')
    if owner and not owner.endswith('@chromium.org'):
      self.RenderHtml('bug_result.html', {
          'error': 'Owner email address must end with @chromium.org.'
      })
      return

    http = oauth2_decorator.decorator.http()
    service = issue_tracker_service.IssueTrackerService(http=http)
    bug_id = service.NewBug(summary, description, labels=labels, owner=owner)
    if not bug_id:
      self.RenderHtml('bug_result.html', {'error': 'Error creating bug!'})
      return

    bug_data.Bug(id=bug_id).put()
    for alert_entity in alerts: