# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import logging
import urllib

from google.appengine.api import urlfetch

from common.buildbot import build
from common.buildbot import network


class Builds(object):

  def __init__(self, master_name, builder_name, url):
    self._master_name = master_name
    self._builder_name = builder_name
    self._url = url

  def __getitem__(self, key):
    """Fetches a Build object containing build details.

    Args:
      key: A nonnegative build number.

    Returns:
      A Build object.

    Raises:
      TypeError: key is not an int.
      ValueError: key is negative.
    """
    # We can't take slices because we don't have a defined length.
    if not isinstance(key, int):
      raise TypeError('build numbers must be integers, not %s' %
                      type(key).__name__)

    return self.Fetch((key,))

  def Fetch(self, build_numbers):
    """Downloads and returns build details.

    If a build has corrupt data, it is not included in the result. If you
    strictly need all the builds requested, be sure to check the result length.

    Args:
      build_numbers: An iterable of build numbers to download.

    Yields:
      Build objects, in the order requested. Some may be missing.

    Raises:
      ValueError: A build number is invalid.
    """
    if not build_numbers:
      return

    for build_number in build_numbers:
      if build_number < 0:
        raise ValueError('Invalid build number: %d' % build_number)

    build_query = urllib.urlencode(
        [('select', build_number) for build_number in build_numbers])
    url = 'json/builders/%s/builds/?%s' % (
        urllib.quote(self._builder_name), build_query)
    url = network.BuildUrl(self._master_name, url)
    try:
      builds = network.FetchData(url).values()
    except (ValueError, urlfetch.ResponseTooLargeError):
      # The JSON decode failed, or the data was too large.
      # Try downloading the builds individually instead.
      builds = []
      for build_number in build_numbers:
        url = 'json/builders/%s/builds/%d' % (
            urllib.quote(self._builder_name), build_number)
        url = network.BuildUrl(self._master_name, url)
        try:
          builds.append(network.FetchData(url))
        except (ValueError, urlfetch.ResponseTooLargeError):
          logging.warning('Unable to fetch %s build %d',
                          self._master_name, build_number)
          continue

    for build_data in builds:
      if 'error' in build_data:
        continue
      yield build.Build(build_data, self._url)
