# Copyright (c) 2009, 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.

import collections
import re
import urllib2

from webkitpy.common.memoized import memoized
from webkitpy.common.net.layout_test_results import LayoutTestResults
from webkitpy.common.net.network_transaction import NetworkTransaction


RESULTS_URL_BASE = 'https://storage.googleapis.com/chromium-layout-test-archives'


class Build(collections.namedtuple('Build', ('builder_name', 'build_number'))):
    """Represents a combination of builder and build number.

    If build number is None, this represents the latest build
    for a given builder.
    """
    def __new__(cls, builder_name, build_number=None):
        return super(Build, cls).__new__(cls, builder_name, build_number)


class BuildBot(object):
    """This class represents an interface to BuildBot-related functionality.

    This includes fetching layout test results from Google Storage;
    for more information about the layout test result format, see:
        https://www.chromium.org/developers/the-json-test-results-format
    """

    def results_url(self, builder_name, build_number=None):
        """Returns a URL for one set of archived layout test results.

        If a build number is given, this will be results for a particular run;
        otherwise it will be the accumulated results URL, which should have
        the latest results.
        """
        if build_number:
            url_base = self.builder_results_url_base(builder_name)
            return '%s/%s/layout-test-results' % (url_base, build_number)
        return self.accumulated_results_url_base(builder_name)

    def builder_results_url_base(self, builder_name):
        """Returns the URL for the given builder's directory in Google Storage.

        Each builder has a directory in the GS bucket, and the directory
        name is the builder name transformed to be more URL-friendly by
        replacing all spaces, periods and parentheses with underscores.
        """
        return '%s/%s' % (RESULTS_URL_BASE, re.sub('[ .()]', '_', builder_name))

    @memoized
    def fetch_retry_summary_json(self, build):
        """Fetches and returns the text of the archived retry_summary file.

        This file is expected to contain the results of retrying layout tests
        with and without a patch in a try job. It includes lists of tests
        that failed only with the patch ("failures"), and tests that failed
        both with and without ("ignored").
        """
        url_base = '%s/%s' % (self.builder_results_url_base(build.builder_name), build.build_number)
        return NetworkTransaction(return_none_on_404=True).run(
            lambda: self._fetch_file(url_base, 'retry_summary.json'))

    def accumulated_results_url_base(self, builder_name):
        return self.builder_results_url_base(builder_name) + '/results/layout-test-results'

    @memoized
    def latest_layout_test_results(self, builder_name):
        return self.fetch_layout_test_results(self.accumulated_results_url_base(builder_name))

    @memoized
    def fetch_results(self, build):
        return self.fetch_layout_test_results(self.results_url(build.builder_name, build.build_number))

    @memoized
    def fetch_layout_test_results(self, results_url):
        """Returns a LayoutTestResults object for results fetched from a given URL."""
        results_file = NetworkTransaction(return_none_on_404=True).run(
            lambda: self._fetch_file(results_url, 'failing_results.json'))
        revision = NetworkTransaction(return_none_on_404=True).run(
            lambda: self._fetch_file(results_url, 'LAST_CHANGE'))
        if not revision:
            results_file = None
        return LayoutTestResults.results_from_string(results_file, revision)

    def _fetch_file(self, url_base, file_name):
        # It seems this can return None if the url redirects and then returns 404.
        # FIXME: This could use Web instead of using urllib2 directly.
        result = urllib2.urlopen('%s/%s' % (url_base, file_name))
        if not result:
            return None
        # urlopen returns a file-like object which sometimes works fine with str()
        # but sometimes is a addinfourl object.  In either case calling read() is correct.
        return result.read()


def current_build_link(host):
    """Returns a link to the current job if running on buildbot, or None."""
    master_name = host.environ.get('BUILDBOT_MASTERNAME')
    builder_name = host.environ.get('BUILDBOT_BUILDERNAME')
    build_number = host.environ.get('BUILDBOT_BUILDNUMBER')
    if not (master_name and builder_name and build_number):
        return None
    return 'https://build.chromium.org/p/%s/builders/%s/builds/%s' % (master_name, builder_name, build_number)


def filter_latest_builds(builds):
    """Filters Build objects to include only the latest for each builder.

    Args:
        builds: A collection of Build objects.

    Returns:
        A list of Build objects; only one Build object per builder name. If
        there are only Builds with no build number, then one is kept; if there
        are Builds with build numbers, then the one with the highest build
        number is kept.
    """
    latest_builds = {}
    for build in builds:
        builder = build.builder_name
        if builder not in latest_builds or build.build_number > latest_builds[builder].build_number:
            latest_builds[builder] = build
    return sorted(latest_builds.values())
