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

"""Routes for CL exonerator."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import httplib
import sys

from chromite.lib import cidb
from chromite.lib import parallel
from chromite.lib import cros_logging as logging
import flask

import config
import debug_routes
import flex_ts_mon.setup
from exonerator import cidblib
from exonerator import gerrit_cq
from exonerator import gerrit_precq
from exonerator import innocent_cls_cq
from exonerator import innocent_cls_precq
from exonerator import weekend


app = flask.Flask(__name__)
app.register_blueprint(debug_routes.app)
config = config.Config()

# TODO(phobbs) make this higher at night / weekend
_CQ_BUILD_LIMIT = 1

APPENGINE_CRON_HEADER = 'X-Appengine-Cron'
PRE_CQ_TYPE = 'pre-cq'
CQ_TYPE = 'cq'

# This must be done at the top level because gunicorn and nginx does not run us
# as __main__
logging.basicConfig(level=logging.DEBUG)


@app.route('/')
def Hello():
  """Placeholder route"""
  return 'hello world'


# Ideally this would be a POST, but Appengine cron only makes GET requests.
@app.route('/cron/exonerate/cq')
def ExonerateCQ():
  """Exonerates innocent CLs which were kicked out."""
  if not _RequestIsFromAppEngineCron():
    flask.abort(httplib.UNAUTHORIZED)

  conn = cidb.CIDBConnection(
      config.cidb_cred_dir, for_service=config.is_service)
  all_exonerated = []
  for batch in innocent_cls_cq.NewInnocentCLs(conn, limit=_CQ_BUILD_LIMIT):
    all_exonerated.extend(_ExonerateBatch(conn, batch, CQ_TYPE))

  return flask.jsonify(exonerated=all_exonerated)


@app.route('/cron/exonerate/pre-cq')
def ExoneratePreCQ():
  """Exonerates innocent CLs which were kicked out."""
  if not _RequestIsFromAppEngineCron():
    flask.abort(httplib.UNAUTHORIZED)

  conn = cidb.CIDBConnection(
      config.cidb_cred_dir, for_service=config.is_service)
  all_exonerated = []
  on_peak = not weekend.HaveUnlimitedResources()
  for batch in innocent_cls_precq.NewInnocentCLs(conn, on_peak=on_peak):
    all_exonerated.extend(_ExonerateBatch(conn, batch, PRE_CQ_TYPE))

  return flask.jsonify(exonerated=all_exonerated)


def _ExonerateBatch(conn, batch, exoneration_type):
  """Exonerates a batch of changes, then inserts CLActions.

  Args:
    conn: The CIDBConnection to use
    batch: A List[exonerator.gerrit_cq.ChangeWithBuild] of changes to exonerate.
    exoneration_type: A string in ('cq', 'pre-cq')
  """
  exonerate_f = {
      'cq': gerrit_cq.MaybeExonerate,
      'pre-cq': gerrit_precq.MaybeExonerate,
  }[exoneration_type]
  exonerated_flags = parallel.RunTasksInProcessPool(
      exonerate_f,
      [[change, build_id] for change, build_id in batch])

  exonerated_changes = []
  for change, exonerated in zip(batch, exonerated_flags):
    if exonerated:
      exonerated_changes.append(change)

  if exonerated_changes:
    cidblib.InsertExoneratedCLActions(
        conn, exonerated_changes, exoneration_type)

  return exonerated_changes


def _RequestIsFromAppEngineCron():
  """Returns whether the request came from Appengine's cron service.

  See https://cloud.google.com/appengine/docs/flexible/python/
      scheduling-jobs-with-cron-yaml#validating_cron_requests
  for more details.
  """
  return flask.request.headers.get(APPENGINE_CRON_HEADER) == 'true'


_METRICS_DEBUG_FILE = '/tmp/metrics-debug.log' if config.debug else None


@app.before_first_request
def SetupWorkerMetrics():
  """Sets up the metrics sending thread.

  This must happen post-fork, or else the gunicorn workers will all use the
  same hostname and task_num arguments, causing conflicts when they flush
  metrics.
  """
  flex_ts_mon.setup.SetupTsMonGlobalState(debug_file=_METRICS_DEBUG_FILE)


if __name__ == '__main__':
  print('Run the app locally with '
        '"gunicorn -c gunicorn.conf.py -b :8080 main:app"', file=sys.stderr)
