# Copyright 2016 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

"""A class to handle cron requests to expunge doomed and deletable projects."""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import logging
import time

from framework import jsonfeed

RUN_DURATION_LIMIT = 50 * 60  # 50 minutes


# TODO: change to FlaskInternalTask when convert to Flask
class Reap(jsonfeed.InternalTask):
  """Look for doomed and deletable projects and delete them."""

  def HandleRequest(self, mr):
    """Update/Delete doomed and deletable projects as needed.

    Args:
      mr: common information parsed from the HTTP request.

    Returns:
      Results dictionary in JSON format. The JSON will look like this:
      {
        'doomed_project_ids': <int>,
        'expunged_project_ids': <int>
      }
      doomed_project_ids are the projects which have been marked as deletable.
      expunged_project_ids are the projects that have either been completely
      expunged or are in the midst of being expunged.
    """
    doomed_project_ids = self._MarkDoomedProjects(mr.cnxn)
    expunged_project_ids = self._ExpungeDeletableProjects(mr.cnxn)
    return {
        'doomed_project_ids': doomed_project_ids,
        'expunged_project_ids': expunged_project_ids,
        }

  def _MarkDoomedProjects(self, cnxn):
    """No longer needed projects get doomed, and this marks them deletable."""
    now = int(time.time())
    doomed_project_rows = self.services.project.project_tbl.Select(
        cnxn, cols=['project_id'],
        # We only match projects with real timestamps and not delete_time = 0.
        where=[('delete_time < %s', [now]), ('delete_time != %s', [0])],
        state='archived', limit=1000)
    doomed_project_ids = [row[0] for row in doomed_project_rows]
    for project_id in doomed_project_ids:
      # Note: We go straight to services layer because this is an internal
      # request, not a request from a user.
      self.services.project.MarkProjectDeletable(
          cnxn, project_id, self.services.config)

    return doomed_project_ids

  def _ExpungeDeletableProjects(self, cnxn):
    """Chip away at deletable projects until they are gone."""
    request_deadline = time.time() + RUN_DURATION_LIMIT

    deletable_project_rows = self.services.project.project_tbl.Select(
        cnxn, cols=['project_id'], state='deletable', limit=100)
    deletable_project_ids = [row[0] for row in deletable_project_rows]
    # expunged_project_ids will contain projects that have either been
    # completely expunged or are in the midst of being expunged.
    expunged_project_ids = set()
    for project_id in deletable_project_ids:
      for _part in self._ExpungeParts(cnxn, project_id):
        expunged_project_ids.add(project_id)
        if time.time() > request_deadline:
          return list(expunged_project_ids)

    return list(expunged_project_ids)

  def _ExpungeParts(self, cnxn, project_id):
    """Delete all data from the specified project, one part at a time.

    This method purges all data associated with the specified project. The
    following is purged:
    * All issues of the project.
    * Project config.
    * Saved queries.
    * Filter rules.
    * Former locations.
    * Local ID counters.
    * Quick edit history.
    * Item stars.
    * Project from the DB.

    Returns a generator whose return values can be either issue
    ids or the specified project id. The returned values are intended to be
    iterated over and not read.
    """
    # Purge all issues of the project.
    while True:
      issue_id_rows = self.services.issue.issue_tbl.Select(
          cnxn, cols=['id'], project_id=project_id, limit=1000)
      issue_ids = [row[0] for row in issue_id_rows]
      for issue_id in issue_ids:
        self.services.issue_star.ExpungeStars(cnxn, issue_id)
      self.services.issue.ExpungeIssues(cnxn, issue_ids)
      yield issue_ids
      break

    # All project purge functions are called with cnxn and project_id.
    project_purge_functions = (
      self.services.config.ExpungeConfig,
      self.services.template.ExpungeProjectTemplates,
      self.services.features.ExpungeSavedQueriesExecuteInProject,
      self.services.features.ExpungeFilterRules,
      self.services.issue.ExpungeFormerLocations,
      self.services.issue.ExpungeLocalIDCounters,
      self.services.features.ExpungeQuickEditHistory,
      self.services.project_star.ExpungeStars,
      self.services.project.ExpungeProject,
    )

    for f in project_purge_functions:
      f(cnxn, project_id)
      yield project_id

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

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