#!/usr/bin/python
#
# Chris Van Hoof -- vanhoof@canonical.com
#  ps-hwe-status-report.py
#
# $ python ps-hwe-linkage-report.py -p <project> -t <tag|all> [-l (list all tags)]
#

import os
import sys
import re
import getopt
import datetime
from launchpadlib.launchpad import Launchpad
from jinja2 import Environment, FileSystemLoader
from optparse import OptionParser

APP_NAME = 'ps-hwe-status-report.py'
SERVICE_ROOT = 'production'
CACHE_DIR = os.path.expanduser('~/.launchpadlib/cache')

hwe_project_name_map = {
    'dell': 'hwe-somerville',
}

def fetch_lp_object():
    lp_object = Launchpad.login_with(APP_NAME, SERVICE_ROOT, CACHE_DIR)
    return lp_object

def lookup_hwe_project_name(name):
    if name in hwe_project_name_map:
        return hwe_project_name_map[name]
    return 'hwe-' + name

class Report(object):
    def __init__(self, project, params = {}):
        self.project = project
 #       self.params = params
        self.planning_bugs = []
        self.enabling_bugs = []
        self.awaiting_rts_bugs = []
        self.awaiting_hw_order_bugs = []
        self.awaiting_hw_received_confirmation_bugs = []
        self.awaiting_certification = []
        self.certification_passed_bugs = []
        self.certification_failed_bugs = []

class Bug(object):
    """ A class to wrap the launchpad bug object, allowing us to set extra
        properties on init """

    hwe_bug_re = re.compile('X-HWE-Project-Matrix:\s*(https://.+)', re.M | re.I)

    def __init__(self, lp_bug):
        self.lp_bug = lp_bug

        # set hwe_bug_id based on bug.description
        self.hwe_bug_id = None
        match = self.hwe_bug_re.search(self.lp_bug.bug.description)
        if match is not None:
            self.hwe_bug_id = match.group(1)

    def __getattr__(self, name):
        if name in self.__dict__.keys():
            return self.__dict__[name]
        return self.lp_bug.__getattr__(name)


def generate_hwe_report(launchpad, pillar_name, date, options):
    pillar = launchpad.projects[pillar_name]

    report = Report(pillar_name)
    report.date = date
#    report.params = {'tag': options.tag}

#    tag_array = ['planning', 'enabling', 'awaiting-rts', 
#                'awaiting-hw-order', 'awaiting-hw-received-confirmation', 
#                'awaiting-certification', 'certification-passed', 
#                'certification-failed']

#    for tag in tag_array:
    bugs = pillar.searchTasks(
        tags="planning",
        status=[
            "New",
            "Confirmed",
            "In Progress",
            "Incomplete",
            "Triaged",
            "Fix Committed",
            "Fix Released",
            "Invalid",
            "Won't Fix"])

    for lp_bug in list(bugs):
        bug = Bug(lp_bug)
        report.planning_bugs.append(bug)


    bugs = pillar.searchTasks(
        tags="enabling",
        status=[
            "New",
            "Confirmed",
            "In Progress",
            "Incomplete",
            "Triaged",
            "Fix Committed",
            "Fix Released",
            "Invalid",
            "Won't Fix"])

    for lp_bug in list(bugs):
        bug = Bug(lp_bug)
        report.enabling_bugs.append(bug)

    
    bugs = pillar.searchTasks(
        tags="awaiting-rts",
        status=[
            "New",
            "Confirmed",
            "In Progress",
            "Incomplete",
            "Triaged",
            "Fix Committed",
            "Fix Released",
            "Invalid",
            "Won't Fix"])

    for lp_bug in list(bugs):
        bug = Bug(lp_bug)
        report.awaiting_rts_bugs.append(bug)


    bugs = pillar.searchTasks(
        tags="awaiting-hw-order",
        status=[
            "New",
            "Confirmed",
            "In Progress",
            "Incomplete",
            "Triaged",
            "Fix Committed",
            "Fix Released",
            "Invalid",
            "Won't Fix"])

    for lp_bug in list(bugs):
        bug = Bug(lp_bug)
        report.awaiting_hw_order_bugs.append(bug)


    bugs = pillar.searchTasks(
        tags="awaiting-hw-received-confirmation",
        status=[
            "New",
            "Confirmed",
            "In Progress",
            "Incomplete",
            "Triaged",
            "Fix Committed",
            "Fix Released",
            "Invalid",
            "Won't Fix"])

    for lp_bug in list(bugs):
        bug = Bug(lp_bug)
        report.awaiting_hw_received_confirmation_bugs.append(bug)

    
    bugs = pillar.searchTasks(
        tags="awaiting-certification",
        status=[
            "New",
            "Confirmed",
            "In Progress",
            "Incomplete",
            "Triaged",
            "Fix Committed",
            "Fix Released",
            "Invalid",
            "Won't Fix"])

    for lp_bug in list(bugs):
        bug = Bug(lp_bug)
        report.awaiting_certification_bugs.append(bug)


    bugs = pillar.searchTasks(
        tags="certification-passed",
        status=[
            "New",
            "Confirmed",
            "In Progress",
            "Incomplete",
            "Triaged",
            "Fix Committed",
            "Fix Released",
            "Invalid",
            "Won't Fix"])

    for lp_bug in list(bugs):
        bug = Bug(lp_bug)
        report.certification_passed_bugs.append(bug)


    bugs = pillar.searchTasks(
        tags="certification-failed",
        status=[
            "New",
            "Confirmed",
            "In Progress",
            "Incomplete",
            "Triaged",
            "Fix Committed",
            "Fix Released",
            "Invalid",
            "Won't Fix"])

    for lp_bug in list(bugs):
        bug = Bug(lp_bug)
        report.certification_failed_bugs.append(bug)


    return report

def main(args):

    usage = 'usage: %prog [options] <project>'
    parser = OptionParser(usage)
    parser.add_option('-o', '--outfile', action = 'store', dest = 'outfile',
                      default = 'index.html', metavar = 'FILE',
                      help = 'write report to FILE')

    (options, args) = parser.parse_args()
    if len(args) != 1:
        parser.error('project argument is required')

    pillar_name = args[0]

    launchpad = fetch_lp_object()
    date = datetime.datetime.now() 

    report = generate_hwe_report(launchpad, pillar_name, date, options)

    env = Environment(loader = FileSystemLoader('.'), autoescape = True)

    def datetimeformat(value, format='%Y-%m-%d'):
        return value.strftime(format)

    env.filters['datetimeformat'] = datetimeformat

    template = env.get_template('status-report.html')
    template.stream(report = report).dump(options.outfile, encoding='utf8')

    return 0


if __name__ == '__main__':
    sys.exit(main(sys.argv))
