#!/usr/bin/env python
# -*- coding: utf-8 -*-

# The MIT License
#
# Copyright 2014 Sony Mobile Communications. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

""" Script to abandon stale changes from the review server.

Fetches a list of open changes that have not been updated since a given age in
days, months or years (default 6 months), and then abandons them.

Requires the user's credentials for the Gerrit server to be declared in the
.netrc file. Supports either basic or digest authentication.

Example to abandon changes that have not been updated for 3 months:

  ./abandon_stale --gerrit-url http://review.example.com/ --age 3months

Supports dry-run mode to only list the stale changes, but not actually
abandon them.

See the --help output for more information about options.

Requires pygerrit2 (https://github.com/dpursehouse/pygerrit2) to be installed
and available for import.

"""

import logging
import optparse
import re
import sys

from pygerrit2.rest import GerritRestAPI
from pygerrit2.rest.auth import HTTPBasicAuthFromNetrc, HTTPDigestAuthFromNetrc


def _main():
    parser = optparse.OptionParser()
    parser.add_option('-g', '--gerrit-url', dest='gerrit_url',
                      metavar='URL',
                      default=None,
                      help='gerrit server URL')
    parser.add_option('-b', '--basic-auth', dest='basic_auth',
                      action='store_true',
                      help='(deprecated) use HTTP basic authentication instead'
                      ' of digest')
    parser.add_option('-d', '--digest-auth', dest='digest_auth',
                      action='store_true',
                      help='use HTTP digest authentication instead of basic')
    parser.add_option('-n', '--dry-run', dest='dry_run',
                      action='store_true',
                      help='enable dry-run mode: show stale changes but do '
                           'not abandon them')
    parser.add_option('-a', '--age', dest='age',
                      metavar='AGE',
                      default="6months",
                      help='age of change since last update in days, months'
                           ' or years (default: %default)')
    parser.add_option('-m', '--message', dest='message',
                      metavar='STRING', default=None,
                      help='custom message to append to abandon message')
    parser.add_option('--branch', dest='branches', metavar='BRANCH_NAME',
                      default=[], action='append',
                      help='abandon changes only on the given branch')
    parser.add_option('--exclude-branch', dest='exclude_branches',
                      metavar='BRANCH_NAME',
                      default=[],
                      action='append',
                      help='do not abandon changes on given branch')
    parser.add_option('--project', dest='projects', metavar='PROJECT_NAME',
                      default=[], action='append',
                      help='abandon changes only on the given project')
    parser.add_option('--exclude-project', dest='exclude_projects',
                      metavar='PROJECT_NAME',
                      default=[],
                      action='append',
                      help='do not abandon changes on given project')
    parser.add_option('--owner', dest='owner',
                      metavar='USERNAME',
                      default=None,
                      action='store',
                      help='only abandon changes owned by the given user')
    parser.add_option('-v', '--verbose', dest='verbose',
                      action='store_true',
                      help='enable verbose (debug) logging')

    (options, _args) = parser.parse_args()

    level = logging.DEBUG if options.verbose else logging.INFO
    logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s',
                        level=level)

    if not options.gerrit_url:
        logging.error("Gerrit URL is required")
        return 1

    pattern = re.compile(r"^([\d]+)(month[s]?|year[s]?|week[s]?)")
    match = pattern.match(options.age)
    if not match:
        logging.error("Invalid age: %s", options.age)
        return 1
    message = "Abandoning after %s %s or more of inactivity." % \
        (match.group(1), match.group(2))

    if options.digest_auth:
        auth_type = HTTPDigestAuthFromNetrc
    else:
        auth_type = HTTPBasicAuthFromNetrc

    try:
        auth = auth_type(url=options.gerrit_url)
        gerrit = GerritRestAPI(url=options.gerrit_url, auth=auth)
    except Exception as e:
        logging.error(e)
        return 1

    logging.info(message)
    try:
        stale_changes = []
        offset = 0
        step = 500
        query_terms = ["status:new", "age:%s" % options.age]
        if options.branches:
            query_terms += ["branch:%s" % b for b in options.branches]
        elif options.exclude_branches:
            query_terms += ["-branch:%s" % b for b in options.exclude_branches]
        if options.projects:
            query_terms += ["project:%s" % p for p in options.projects]
        elif options.exclude_projects:
            query_terms = ["-project:%s" % p for p in options.exclude_projects]
        if options.owner:
            query_terms += ["owner:%s" % options.owner]
        query = "%20".join(query_terms)
        while True:
            q = query + "&o=DETAILED_ACCOUNTS&n=%d&S=%d" % (step, offset)
            logging.debug("Query: %s", q)
            url = "/changes/?q=" + q
            result = gerrit.get(url)
            logging.debug("%d changes", len(result))
            if not result:
                break
            stale_changes += result
            last = result[-1]
            if "_more_changes" in last:
                logging.debug("More...")
                offset += step
            else:
                break
    except Exception as e:
        logging.error(e)
        return 1

    abandoned = 0
    errors = 0
    abandon_message = message
    if options.message:
        abandon_message += "\n\n" + options.message
    for change in stale_changes:
        number = change["_number"]
        try:
            owner = change["owner"]["name"]
        except:
            owner = "Unknown"
        subject = change["subject"]
        if len(subject) > 70:
            subject = subject[:65] + " [...]"
        change_id = change["id"]
        logging.info("%s (%s): %s", number, owner, subject)
        if options.dry_run:
            continue

        try:
            gerrit.post("/changes/" + change_id + "/abandon",
                        json={"message" : "%s" % abandon_message})
            abandoned += 1
        except Exception as e:
            errors += 1
            logging.error(e)
    logging.info("Total %d stale open changes", len(stale_changes))
    if not options.dry_run:
        logging.info("Abandoned %d changes. %d errors.", abandoned, errors)

if __name__ == "__main__":
    sys.exit(_main())
