# 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 collections
import cPickle
import json
import logging
import os
import re
import socket
import time
import urllib
import urllib2


PENDING = None
SUCCESS = 0
WARNING = 1
FAILURE = 2
EXCEPTION = 4
SLAVE_LOST = 5


BASE_URL = 'http://build.chromium.org/p'
CACHE_FILE_NAME = 'cache.dat'


StackTraceLine = collections.namedtuple(
    'StackTraceLine', ('file', 'function', 'line', 'source'))


def _FetchData(master, url):
  url = '%s/%s/json/%s' % (BASE_URL, master, url)
  try:
    logging.info('Retrieving ' + url)
    return json.load(urllib2.urlopen(url))
  except (urllib2.HTTPError, socket.error):
    # Could be intermittent; try again.
    try:
      return json.load(urllib2.urlopen(url))
    except (urllib2.HTTPError, socket.error):
      logging.error('Error retrieving URL ' + url)
      raise
  except:
    logging.error('Error retrieving URL ' + url)
    raise


def Builders(master):
  builders = {}

  # Load builders from cache file.
  if os.path.exists(master):
    start_time = time.time()
    for builder_name in os.listdir(master):
      cache_file_path = os.path.join(master, builder_name, CACHE_FILE_NAME)
      if os.path.exists(cache_file_path):
        with open(cache_file_path, 'rb') as cache_file:
          try:
            builders[builder_name] = cPickle.load(cache_file)
          except EOFError:
            logging.error('File is corrupted: %s', cache_file_path)
            raise
    logging.info('Loaded builder caches in %0.2f seconds.',
                 time.time() - start_time)

  return builders


def Update(master, builders):
  # Update builders with latest information.
  builder_data = _FetchData(master, 'builders')
  for builder_name, builder_info in builder_data.iteritems():
    if builder_name in builders:
      builders[builder_name].Update(builder_info)
    else:
      builders[builder_name] = Builder(master, builder_name, builder_info)

  return builders


class Builder(object):
  def __init__(self, master, name, data):
    self._master = master
    self._name = name

    self.Update(data)

    self._builds = {}

  def __setstate__(self, state):
    self.__dict__ = state  # pylint: disable=attribute-defined-outside-init
    if not hasattr(self, '_builds'):
      self._builds = {}

  def __lt__(self, other):
    return self.name < other.name

  def __str__(self):
    return self.name

  def __getitem__(self, key):
    if not isinstance(key, int):
      raise TypeError('build numbers must be integers, not %s' %
                      type(key).__name__)

    self._FetchBuilds(key)
    return self._builds[key]

  def _FetchBuilds(self, *build_numbers):
    """Download build details, if not already cached.

    Returns:
      A tuple of downloaded build numbers.
    """
    build_numbers = tuple(build_number for build_number in build_numbers
                          if not (build_number in self._builds and
                          self._builds[build_number].complete))
    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) for build in build_numbers])
    url = 'builders/%s/builds/?%s' % (urllib.quote(self.name), build_query)
    builds = _FetchData(self.master, url)
    for build_info in builds.itervalues():
      self._builds[build_info['number']] = Build(self.master, build_info)

    self._Cache()

    return build_numbers

  def FetchRecentBuilds(self, number_of_builds):
    min_build = max(self.last_build - number_of_builds, -1)
    return self._FetchBuilds(*xrange(self.last_build, min_build, -1))

  def Update(self, data=None):
    if not data:
      data = _FetchData(self.master, 'builders/%s' % urllib.quote(self.name))
    self._state = data['state']
    self._pending_build_count = data['pendingBuilds']
    self._current_builds = tuple(data['currentBuilds'])
    self._cached_builds = tuple(data['cachedBuilds'])
    self._slaves = tuple(data['slaves'])

    self._Cache()

  def _Cache(self):
    cache_dir_path = os.path.join(self.master, self.name)
    if not os.path.exists(cache_dir_path):
      os.makedirs(cache_dir_path)
    cache_file_path = os.path.join(cache_dir_path, CACHE_FILE_NAME)
    with open(cache_file_path, 'wb') as cache_file:
      cPickle.dump(self, cache_file, -1)

  def LastBuilds(self, count):
    min_build = max(self.last_build - count, -1)
    for build_number in xrange(self.last_build, min_build, -1):
      yield self._builds[build_number]

  @property
  def master(self):
    return self._master

  @property
  def name(self):
    return self._name

  @property
  def state(self):
    return self._state

  @property
  def pending_build_count(self):
    return self._pending_build_count

  @property
  def current_builds(self):
    """List of build numbers currently building.

    There may be multiple entries if there are multiple build slaves."""
    return self._current_builds

  @property
  def cached_builds(self):
    """Builds whose data are visible on the master in increasing order.

    More builds may be available than this."""
    return self._cached_builds

  @property
  def last_build(self):
    """Last completed build."""
    for build_number in reversed(self.cached_builds):
      if build_number not in self.current_builds:
        return build_number
    return None

  @property
  def slaves(self):
    return self._slaves


class Build(object):
  def __init__(self, master, data):
    self._master = master
    self._builder_name = data['builderName']
    self._number = data['number']
    self._complete = not ('currentStep' in data and data['currentStep'])
    self._start_time, self._end_time = data['times']

    self._steps = {step_info['name']:
        Step(self._master, self._builder_name, self._number, step_info)
        for step_info in data['steps']}

  def __str__(self):
    return str(self.number)

  def __lt__(self, other):
    return self.number < other.number

  @property
  def builder_name(self):
    return self._builder_name

  @property
  def number(self):
    return self._number

  @property
  def complete(self):
    return self._complete

  @property
  def start_time(self):
    return self._start_time

  @property
  def end_time(self):
    return self._end_time

  @property
  def steps(self):
    return self._steps


def _ParseTraceFromLog(log):
  """Search the log for a stack trace and return a structured representation.

  This function supports both default Python-style stacks and Telemetry-style
  stacks. It returns the first stack trace found in the log - sometimes a bug
  leads to a cascade of failures, so the first one is usually the root cause.
  """
  log_iterator = iter(log.splitlines())
  for line in log_iterator:
    if line == 'Traceback (most recent call last):':
      break
  else:
    return (None, None)

  stack_trace = []
  while True:
    line = log_iterator.next()
    match1 = re.match(r'\s*File "(?P<file>.+)", line (?P<line>[0-9]+), '
                      'in (?P<function>.+)', line)
    match2 = re.match(r'\s*(?P<function>.+) at '
                      '(?P<file>.+):(?P<line>[0-9]+)', line)
    match = match1 or match2
    if not match:
      exception = line
      break
    trace_line = match.groupdict()
    # Use the base name, because the path will be different
    # across platforms and configurations.
    file_base_name = trace_line['file'].split('/')[-1].split('\\')[-1]
    source = log_iterator.next().strip()
    stack_trace.append(StackTraceLine(
        file_base_name, trace_line['function'], trace_line['line'], source))

  return tuple(stack_trace), exception


class Step(object):
  def __init__(self, master, builder_name, build_number, data):
    self._master = master
    self._builder_name = builder_name
    self._build_number = build_number
    self._name = data['name']
    self._result = data['results'][0]
    self._start_time, self._end_time = data['times']

    self._log_link = None
    self._results_link = None
    for link_name, link_url in data['logs']:
      if link_name == 'stdio':
        self._log_link = link_url + '/text'
      elif link_name == 'json.output':
        self._results_link = link_url + '/text'

    self._log = None
    self._results = None
    self._stack_trace = None

  def __getstate__(self):
    return {
      '_master': self._master,
      '_builder_name': self._builder_name,
      '_build_number': self._build_number,
      '_name': self._name,
      '_result': self._result,
      '_start_time': self._start_time,
      '_end_time': self._end_time,
      '_log_link': self._log_link,
      '_results_link': self._results_link,
    }

  def __setstate__(self, state):
    self.__dict__ = state  # pylint: disable=attribute-defined-outside-init
    self._log = None
    self._results = None
    self._stack_trace = None

  def __str__(self):
    return self.name

  @property
  def name(self):
    return self._name

  @property
  def result(self):
    return self._result

  @property
  def start_time(self):
    return self._start_time

  @property
  def end_time(self):
    return self._end_time

  @property
  def log_link(self):
    return self._log_link

  @property
  def results_link(self):
    return self._results_link

  @property
  def log(self):
    if self._log is None:
      if not self.log_link:
        return None
      cache_file_path = os.path.join(
          self._master, self._builder_name,
          str(self._build_number), self._name, 'log')
      if os.path.exists(cache_file_path):
        # Load cache file, if it exists.
        with open(cache_file_path, 'rb') as cache_file:
          self._log = cache_file.read()
      else:
        # Otherwise, download it.
        logging.info('Retrieving ' + self.log_link)
        try:
          data = urllib2.urlopen(self.log_link).read()
        except (urllib2.HTTPError, socket.error):
          # Could be intermittent; try again.
          try:
            data = urllib2.urlopen(self.log_link).read()
          except (urllib2.HTTPError, socket.error):
            logging.error('Error retrieving URL ' + self.log_link)
            raise
        except:
          logging.error('Error retrieving URL ' + self.log_link)
          raise
        # And cache the newly downloaded data.
        cache_dir_path = os.path.dirname(cache_file_path)
        if not os.path.exists(cache_dir_path):
          os.makedirs(cache_dir_path)
        with open(cache_file_path, 'wb') as cache_file:
          cache_file.write(data)
        self._log = data
    return self._log

  @property
  def results(self):
    if self._results is None:
      if not self.results_link:
        return None
      cache_file_path = os.path.join(
          self._master, self._builder_name,
          str(self._build_number), self._name, 'results')
      if os.path.exists(cache_file_path):
        # Load cache file, if it exists.
        try:
          with open(cache_file_path, 'rb') as cache_file:
            self._results = cPickle.load(cache_file)
        except EOFError:
          os.remove(cache_file_path)
          return self.results
      else:
        # Otherwise, download it.
        logging.info('Retrieving ' + self.results_link)
        try:
          data = json.load(urllib2.urlopen(self.results_link))
        except (urllib2.HTTPError, socket.error):
          # Could be intermittent; try again.
          try:
            data = json.load(urllib2.urlopen(self.results_link))
          except (urllib2.HTTPError, socket.error):
            logging.error('Error retrieving URL ' + self.results_link)
            raise
        except ValueError:
          # If the build had an exception, the results might not be valid.
          data = None
        except:
          logging.error('Error retrieving URL ' + self.results_link)
          raise
        # And cache the newly downloaded data.
        cache_dir_path = os.path.dirname(cache_file_path)
        if not os.path.exists(cache_dir_path):
          os.makedirs(cache_dir_path)
        with open(cache_file_path, 'wb') as cache_file:
          cPickle.dump(data, cache_file, -1)
        self._results = data
    return self._results

  @property
  def stack_trace(self):
    if self._stack_trace is None:
      self._stack_trace = _ParseTraceFromLog(self.log)
    return self._stack_trace

  @property
  def chrome_stack_trace(self):
    raise NotImplementedError()
