#!/usr/bin/env python

# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

"""
Track test skips via launchpadlib API and raise alerts if a bug
is fixed but a skip is still in the Tempest test code
"""

import os
import re

from launchpadlib import launchpad
from oslo_log import log as logging

BASEDIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
TESTDIR = os.path.join(BASEDIR, 'tempest')
LPCACHEDIR = os.path.expanduser('~/.launchpadlib/cache')

LOG = logging.getLogger(__name__)


def info(msg, *args, **kwargs):
    LOG.info(msg, *args, **kwargs)


def debug(msg, *args, **kwargs):
    LOG.debug(msg, *args, **kwargs)


def find_skips(start=TESTDIR):
    """Find skipped tests

    Returns a list of tuples (method, bug) that represent
    test methods that have been decorated to skip because of
    a particular bug.
    """
    results = {}
    debug("Searching in %s", start)
    for root, _dirs, files in os.walk(start):
        for name in files:
            if name.startswith('test_') and name.endswith('py'):
                path = os.path.join(root, name)
                debug("Searching in %s", path)
                temp_result = find_skips_in_file(path)
                for method_name, bug_no in temp_result:
                    if results.get(bug_no):
                        result_dict = results.get(bug_no)
                        if result_dict.get(name):
                            result_dict[name].append(method_name)
                        else:
                            result_dict[name] = [method_name]
                        results[bug_no] = result_dict
                    else:
                        results[bug_no] = {name: [method_name]}
    return results


def find_skips_in_file(path):
    """Return the skip tuples in a test file"""
    BUG_RE = re.compile(r'\s*@.*skip_because\(bug=[\'"](\d+)[\'"]')
    DEF_RE = re.compile(r'\s*def (\w+)\(')
    bug_found = False
    results = []
    with open(path, 'rb') as content:
        lines = content.readlines()
        for x, line in enumerate(lines):
            if not bug_found:
                res = BUG_RE.match(line)
                if res:
                    bug_no = int(res.group(1))
                    debug("Found bug skip %s on line %d", bug_no, x + 1)
                    bug_found = True
            else:
                res = DEF_RE.match(line)
                if res:
                    method = res.group(1)
                    debug("Found test method %s skips for bug %d",
                          method, bug_no)
                    results.append((method, bug_no))
                    bug_found = False
    return results


def get_results(result_dict):
    results = []
    for bug_no in result_dict:
        for method in result_dict[bug_no]:
            results.append((method, bug_no))
    return results


if __name__ == '__main__':
    results = find_skips()
    unique_bugs = sorted(set([bug for (method, bug) in get_results(results)]))
    unskips = []
    duplicates = []
    info("Total bug skips found: %d", len(results))
    info("Total unique bugs causing skips: %d", len(unique_bugs))
    lp = launchpad.Launchpad.login_anonymously('grabbing bugs',
                                               'production',
                                               LPCACHEDIR)
    for bug_no in unique_bugs:
        bug = lp.bugs[bug_no]
        duplicate = bug.duplicate_of_link
        if duplicate is not None:
            dup_id = duplicate.split('/')[-1]
            duplicates.append((bug_no, dup_id))
        for task in bug.bug_tasks:
            info("Bug #%7s (%12s - %12s)", bug_no,
                 task.importance, task.status)
            if task.status in ('Fix Released', 'Fix Committed'):
                unskips.append(bug_no)

    for bug_id, dup_id in duplicates:
        if bug_id not in unskips:
            dup_bug = lp.bugs[dup_id]
            for task in dup_bug.bug_tasks:
                info("Bug #%7s is a duplicate of Bug#%7s (%12s - %12s)",
                     bug_id, dup_id, task.importance, task.status)
                if task.status in ('Fix Released', 'Fix Committed'):
                    unskips.append(bug_id)

    unskips = sorted(set(unskips))
    if unskips:
        print("The following bugs have been fixed and the corresponding skips")
        print("should be removed from the test cases:")
        print()
        for bug in unskips:
            message = "  %7s in " % bug
            locations = ["%s" % x for x in results[bug].keys()]
            message += " and ".join(locations)
            print(message)
