#!/usr/bin/env python2
# Copyright 2010-2011, Canonical, Ltd.
# Author: Jamie Strandboge <jamie@canonical.com>
# License: GPLv3
#
# $UCT/scripts/report-bugs --reduced >> bugs/open.csv
#
from __future__ import print_function

import cve_lib
import optparse
import os
import re
import subprocess
import sys
import time

parser = optparse.OptionParser()
parser.add_option("--debug", help="Verbose processing output", action='store_true')
parser.add_option("--reduced", help="Reduced output", action='store_true')
parser.add_option("--team", help="Find bugs for team", metavar="TEAM", action='store', default='ubuntu-security')
parser.add_option("-s", "--status", help="Specify status for bugs", metavar="STATUS", action='store', default=None)
parser.add_option("-i", "--importance", help="Specify importance for bugs", metavar="STATUS", action='store', default=None)

(opt, args) = parser.parse_args()

def debug(s):
    '''Print debug message'''
    if opt.debug:
        os.write(sys.stderr.fileno(), "DEBUG: %s" % (s))

def printmsg(s):
    '''Print msg'''
    os.write(sys.stdout.fileno(), "%s" % (s))

#
# Connect to Launchpad
#
try:
    import lpl_common
except:
    print("lpl_common.py seems to be missing.  Please create a symlink from $UQT/common/lpl_common.py to $UCT/scripts/", file=sys.stderr)
    sys.exit(1)

# Load configuration
cve_lib.read_config()

# API interface
debug("Connecting to LP ...\n")
lp = lpl_common.connect()

# Get authenticated URL fetcher
opener = lpl_common.opener_with_cookie(cve_lib.config["plb_authentication"])
if not opener:
    raise ValueError("Could not open cookies")

ubuntu = lp.distributions['ubuntu']
debug("Distribution: %s\n" % ubuntu)
team = lp.people[opt.team]
debug("Team: %s\n" % team)
debug("done\n")

# Order is important for CSV generation! Add to end if needed
importances = ['Unknown', 'Critical', 'High', 'Medium', 'Low', 'Wishlist', 'Undecided']
importance_tallies = dict((key, 0) for key in importances)
statuses = ['New', 'Incomplete', 'Confirmed', 'Triaged', 'In Progress', 'Fix Committed']
status_tallies = dict((key, 0) for key in statuses)

# Get all the bug for the team that match the specified status and importance
if opt.importance:
    importances = [opt.importance]

if opt.status:
    statuses = [opt.status]

debug("Loading bugs...\n")
bugs = {}
unique_bugs = set([])
for rel in cve_lib.releases + ['ubuntu']:
    if rel == 'ubuntu':
        obj = ubuntu
    else:
        series = ubuntu.getSeries(name_or_version=rel)
        if not series.active:
            continue
        obj = series

    task_collection = obj.searchTasks(bug_subscriber=team, omit_targeted=False, omit_duplicates=True, importance=importances, status=statuses)

    for task in task_collection:
        bugid = task.bug.id
        k = "%d:%s" % (bugid, rel)
        if k not in bugs:
            bugs[k] = task

        unique_bugs.add(bugid)
debug("done\n")

debug("Processing bugs...")
# Now go through all the bugs
importances_seen = set([])
keys = sorted(list(bugs.keys()))

# these reduce http requests significantly
bugs_by_status = dict((key, set([])) for key in statuses)
bugs_by_importance = dict((key, set([])) for key in importances)

for k in keys:
    task = bugs[k]
    bugid = k.split(":")[0]

    # Do statuses by series, since each task represents real work
    status = task.status
    if status in statuses:
        status_tallies[status] += 1
        bugs_by_status[status].add(bugid)

    # Do importances by source package only
    importance = task.importance
    pkg = task.bug_target_name.split(' (',1)[0]

    k = "%s:%s" % (pkg, importance)
    if k not in importances_seen and importance in importances:
        importance_tallies[importance] += 1
        importances_seen.add(k)
        bugs_by_importance[importance].add(bugid)

debug("done\n")

# print Status. If reduced, then print CSV
if opt.reduced:
    printmsg("# [S]tatus:[Date]")
    for i in statuses:
        printmsg(":<%s>" % i)
    printmsg("\n")
    printmsg("S:%s" % (time.strftime("%Y-%m-%d", time.gmtime())))

for i in statuses:
    if opt.reduced:
        printmsg(":%d" % (status_tallies[i]))
    else:
        printmsg("%s: %d\n" % (i, status_tallies[i]))
        for bugid in bugs_by_status[i]:
            printmsg(" https://launchpad.net/bugs/%s\n" % (bugid))

if opt.reduced:
    printmsg("\n")

# print Importance. If reduced, then print CSV
if opt.reduced:
    printmsg("# [I]mportance:[Date]")
    for i in importances:
        printmsg(":<%s>" % i)
    printmsg("\n")
    printmsg("I:%s" % (time.strftime("%Y-%m-%d", time.gmtime())))

for i in importances:
    if opt.reduced:
        printmsg(":%d" % (importance_tallies[i]))
    else:
        printmsg("%s: %d\n" % (i, importance_tallies[i]))

        for bugid in bugs_by_importance[i]:
            printmsg(" https://launchpad.net/bugs/%s\n" % (bugid))

if opt.reduced:
    printmsg("\n")

sys.exit(0)

