#!/usr/bin/env vpython
#
# Copyright (C) 2013 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""Prints a list of test expectations for tests whose bugs haven't been modified recently."""

import csv
import datetime
import json
import optparse
import StringIO
import sys
import urllib2

from blinkpy.common.host import Host
from blinkpy.web_tests.models.test_expectations import TestExpectationParser

# FIXME: Make this a direct request to Monorail.
GOOGLE_CODE_URL = 'https://www.googleapis.com/projecthosting/v2/projects/chromium/issues/%s?key=AIzaSyDgCqT1Dt5AZWLHo4QJjyMHaCjhnFacGF0'
CRBUG_PREFIX = 'crbug.com/'
CSV_ROW_HEADERS = ['crbug link', 'test file', 'days since last update', 'owner', 'status']

class BugInfo():
    def __init__(self, bug_link, filename, days_since_last_update, owner, status):
        self.bug_link = bug_link
        self.filename = filename
        self.days_since_last_update = days_since_last_update
        self.owner = owner
        self.status = status

class StaleTestPrinter(object):

    def __init__(self, options):
        self.days = options.days
        self.csv_filename = options.create_csv
        self.host = Host()
        self.bug_info = {}

    def print_stale_tests(self):
        port = self.host.port_factory.get()
        expectations = port.expectations_dict()
        parser = TestExpectationParser(port, all_tests=(), is_lint_mode=False)
        expectations_file, expectations_contents = expectations.items()[0]
        expectation_lines = parser.parse(expectations_file, expectations_contents)
        csv_rows = []
        for line in expectation_lines:
            row = self.check_expectations_line(line)
            if row:
                csv_rows.append(row)
        if self.csv_filename:
            self.write_csv(csv_rows)

    def write_csv(self, rows):
        out = StringIO.StringIO()
        writer = csv.writer(out)
        writer.writerow(CSV_ROW_HEADERS)
        for row in rows:
            writer.writerow(row)
        self.host.filesystem.write_text_file(self.csv_filename, out.getvalue())

    def check_expectations_line(self, line):
        """Checks the bugs in one test expectations line to see if they're stale.

        Args:
            line: A TestExpectationsLine instance.

        Returns:
            A CSV row (a list of strings), or None if there are no stale bugs.
        """
        bug_links, test_name = line.bugs, line.name
        try:
            if bug_links:
                # Prepopulate bug info.
                for bug_link in bug_links:
                    self.populate_bug_info(bug_link, test_name);
                # Return the stale bug's information.
                if all(self.is_stale(bug_link) for bug_link in bug_links):
                    print line.original_string.strip()
                    return [bug_links[0], self.bug_info[bug_links[0]].filename,
                            self.bug_info[bug_links[0]].days_since_last_update,
                            self.bug_info[bug_links[0]].owner,
                            self.bug_info[bug_links[0]].status]
        except urllib2.HTTPError as error:
            if error.code == 404:
                message = 'got 404, bug does not exist.'
            elif error.code == 403:
                message = 'got 403, not accessible. Not able to tell if it\'s stale.'
            else:
                message = str(error)
            print >> sys.stderr, 'Error when checking %s: %s' % (','.join(bug_links), message)
        return None

    def populate_bug_info(self, bug_link, test_name):
        if bug_link in self.bug_info:
            return
        # In case there's an error in the request, don't make the same request again.
        bug_number = bug_link.strip(CRBUG_PREFIX)
        url = GOOGLE_CODE_URL % bug_number
        response = urllib2.urlopen(url)
        parsed = json.loads(response.read())
        parsed_time = datetime.datetime.strptime(parsed['updated'].split(".")[0] + "UTC", "%Y-%m-%dT%H:%M:%S%Z")
        time_delta = datetime.datetime.now() - parsed_time
        owner = 'none'
        if 'owner' in parsed.keys():
            owner = parsed['owner']['name']
        self.bug_info[bug_link] = BugInfo(bug_link, test_name, time_delta.days, owner, parsed['state'])

    def is_stale(self, bug_link):
        return self.bug_info[bug_link].days_since_last_update > self.days


def main(argv):
    option_parser = optparse.OptionParser()
    option_parser.add_option(
        '--days', type='int', default=90,
        help='Number of days to consider a bug stale.')
    option_parser.add_option(
        '--create-csv', type='string', default='',
        help='Filename of CSV file to write stale entries to. No file will be written if no name specified.')
    options, _ = option_parser.parse_args(argv)
    printer = StaleTestPrinter(options)
    printer.print_stale_tests()
    return 0


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