# Copyright 2014 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.

#
# Most of this file was ported over from Blink's
# tools/blinkpy/web_tests/layout_package/json_results_generator.py
# tools/blinkpy/common/net/file_uploader.py
#

import json
import logging
import mimetypes
import os
import time
import urllib2

_log = logging.getLogger(__name__)

_JSON_PREFIX = 'ADD_RESULTS('
_JSON_SUFFIX = ');'


def HasJSONWrapper(string):
  return string.startswith(_JSON_PREFIX) and string.endswith(_JSON_SUFFIX)


def StripJSONWrapper(json_content):
  # FIXME: Kill this code once the server returns json instead of jsonp.
  if HasJSONWrapper(json_content):
    return json_content[len(_JSON_PREFIX):len(json_content) - len(_JSON_SUFFIX)]
  return json_content


def WriteJSON(json_object, file_path, callback=None):
  # Specify separators in order to get compact encoding.
  json_string = json.dumps(json_object, separators=(',', ':'))
  if callback:
    json_string = callback + '(' + json_string + ');'
  with open(file_path, 'w') as fp:
    fp.write(json_string)


def ConvertTrieToFlatPaths(trie, prefix=None):
  """Flattens the trie of paths, prepending a prefix to each."""
  result = {}
  for name, data in trie.iteritems():
    if prefix:
      name = prefix + '/' + name

    if len(data) and not 'results' in data:
      result.update(ConvertTrieToFlatPaths(data, name))
    else:
      result[name] = data

  return result


def AddPathToTrie(path, value, trie):
  """Inserts a single path and value into a directory trie structure."""
  if not '/' in path:
    trie[path] = value
    return

  directory, _, rest = path.partition('/')
  if not directory in trie:
    trie[directory] = {}
  AddPathToTrie(rest, value, trie[directory])


def TestTimingsTrie(individual_test_timings):
  """Breaks a test name into dicts by directory

  foo/bar/baz.html: 1ms
  foo/bar/baz1.html: 3ms

  becomes
  foo: {
      bar: {
          baz.html: 1,
          baz1.html: 3
      }
  }
  """
  trie = {}
  for test_result in individual_test_timings:
    test = test_result.test_name

    AddPathToTrie(test, int(1000 * test_result.test_run_time), trie)

  return trie


class TestResult(object):
  """A simple class that represents a single test result."""

  # Test modifier constants.
  (NONE, FAILS, FLAKY, DISABLED) = range(4)

  def __init__(self, test, failed=False, elapsed_time=0):
    self.test_name = test
    self.failed = failed
    self.test_run_time = elapsed_time

    test_name = test
    try:
      test_name = test.split('.')[1]
    except IndexError:
      _log.warn('Invalid test name: %s.', test)

    if test_name.startswith('FAILS_'):
      self.modifier = self.FAILS
    elif test_name.startswith('FLAKY_'):
      self.modifier = self.FLAKY
    elif test_name.startswith('DISABLED_'):
      self.modifier = self.DISABLED
    else:
      self.modifier = self.NONE

  def Fixable(self):
    return self.failed or self.modifier == self.DISABLED


class JSONResultsGeneratorBase(object):
  """A JSON results generator for generic tests."""

  MAX_NUMBER_OF_BUILD_RESULTS_TO_LOG = 750
  # Min time (seconds) that will be added to the JSON.
  MIN_TIME = 1

  # Note that in non-chromium tests those chars are used to indicate
  # test modifiers (FAILS, FLAKY, etc) but not actual test results.
  PASS_RESULT = 'P'
  SKIP_RESULT = 'X'
  FAIL_RESULT = 'F'
  FLAKY_RESULT = 'L'
  NO_DATA_RESULT = 'N'

  MODIFIER_TO_CHAR = {TestResult.NONE: PASS_RESULT,
                      TestResult.DISABLED: SKIP_RESULT,
                      TestResult.FAILS: FAIL_RESULT,
                      TestResult.FLAKY: FLAKY_RESULT}

  VERSION = 4
  VERSION_KEY = 'version'
  RESULTS = 'results'
  TIMES = 'times'
  BUILD_NUMBERS = 'buildNumbers'
  TIME = 'secondsSinceEpoch'
  TESTS = 'tests'

  FIXABLE_COUNT = 'fixableCount'
  FIXABLE = 'fixableCounts'
  ALL_FIXABLE_COUNT = 'allFixableCount'

  RESULTS_FILENAME = 'results.json'
  TIMES_MS_FILENAME = 'times_ms.json'
  INCREMENTAL_RESULTS_FILENAME = 'incremental_results.json'

  # line too long pylint: disable=line-too-long
  URL_FOR_TEST_LIST_JSON = (
      'https://%s/testfile?builder=%s&name=%s&testlistjson=1&testtype=%s&'
      'master=%s')
  # pylint: enable=line-too-long

  def __init__(self, builder_name, build_name, build_number,
               results_file_base_path, builder_base_url,
               test_results_map, svn_repositories=None,
               test_results_server=None,
               test_type='',
               master_name=''):
    """Modifies the results.json file. Grabs it off the archive directory
    if it is not found locally.

    Args
      builder_name: the builder name (e.g. Webkit).
      build_name: the build name (e.g. webkit-rel).
      build_number: the build number.
      results_file_base_path: Absolute path to the directory containing the
          results json file.
      builder_base_url: the URL where we have the archived test results.
          If this is None no archived results will be retrieved.
      test_results_map: A dictionary that maps test_name to TestResult.
      svn_repositories: A (json_field_name, svn_path) pair for SVN
          repositories that tests rely on.  The SVN revision will be
          included in the JSON with the given json_field_name.
      test_results_server: server that hosts test results json.
      test_type: test type string (e.g. 'layout-tests').
      master_name: the name of the buildbot master.
    """
    self._builder_name = builder_name
    self._build_name = build_name
    self._build_number = build_number
    self._builder_base_url = builder_base_url
    self._results_directory = results_file_base_path

    self._test_results_map = test_results_map
    self._test_results = test_results_map.values()

    self._svn_repositories = svn_repositories
    if not self._svn_repositories:
      self._svn_repositories = {}

    self._test_results_server = test_results_server
    self._test_type = test_type
    self._master_name = master_name

    self._archived_results = None

  def GenerateJSONOutput(self):
    json_object = self.GetJSON()
    if json_object:
      file_path = (
          os.path.join(
              self._results_directory,
              self.INCREMENTAL_RESULTS_FILENAME))
      WriteJSON(json_object, file_path)

  def GenerateTimesMSFile(self):
    times = TestTimingsTrie(self._test_results_map.values())
    file_path = os.path.join(self._results_directory, self.TIMES_MS_FILENAME)
    WriteJSON(times, file_path)

  def GetJSON(self):
    """Gets the results for the results.json file."""
    results_json = {}

    if not results_json:
      results_json, error = self._GetArchivedJSONResults()
      if error:
        # If there was an error don't write a results.json
        # file at all as it would lose all the information on the
        # bot.
        _log.error('Archive directory is inaccessible. Not '
                   'modifying or clobbering the results.json '
                   'file: ' + str(error))
        return None

    builder_name = self._builder_name
    if results_json and builder_name not in results_json:
      _log.debug('Builder name (%s) is not in the results.json file.',
                 builder_name)

    self._ConvertJSONToCurrentVersion(results_json)

    if builder_name not in results_json:
      results_json[builder_name] = (
          self._CreateResultsForBuilderJSON())

    results_for_builder = results_json[builder_name]

    if builder_name:
      self._InsertGenericMetaData(results_for_builder)

    self._InsertFailureSummaries(results_for_builder)

    # Update the all failing tests with result type and time.
    tests = results_for_builder[self.TESTS]
    all_failing_tests = self._GetFailedTestNames()
    all_failing_tests.update(ConvertTrieToFlatPaths(tests))

    for test in all_failing_tests:
      self._InsertTestTimeAndResult(test, tests)

    return results_json

  def SetArchivedResults(self, archived_results):
    self._archived_results = archived_results

  def UploadJSONFiles(self, json_files):
    """Uploads the given json_files to the test_results_server (if the
    test_results_server is given)."""
    if not self._test_results_server:
      return

    if not self._master_name:
      _log.error(
          '--test-results-server was set, but --master-name was not.  Not '
          'uploading JSON files.')
      return

    _log.info('Uploading JSON files for builder: %s', self._builder_name)
    attrs = [('builder', self._builder_name),
             ('testtype', self._test_type),
             ('master', self._master_name)]

    files = [(json_file, os.path.join(self._results_directory, json_file))
             for json_file in json_files]

    url = 'https://%s/testfile/upload' % self._test_results_server
    # Set uploading timeout in case appengine server is having problems.
    # 120 seconds are more than enough to upload test results.
    uploader = _FileUploader(url, 120)
    try:
      response = uploader.UploadAsMultipartFormData(files, attrs)
      if response:
        if response.code == 200:
          _log.info('JSON uploaded.')
        else:
          _log.debug(
              "JSON upload failed, %d: '%s'", response.code, response.read())
      else:
        _log.error('JSON upload failed; no response returned')
    except Exception as err: # pylint: disable=broad-except
      _log.error('Upload failed: %s', err)
      return

  def _GetTestTiming(self, test_name):
    """Returns test timing data (elapsed time) in second
    for the given test_name."""
    if test_name in self._test_results_map:
      # Floor for now to get time in seconds.
      return int(self._test_results_map[test_name].test_run_time)
    return 0

  def _GetFailedTestNames(self):
    """Returns a set of failed test names."""
    return set([r.test_name for r in self._test_results if r.failed])

  def _GetModifierChar(self, test_name):
    """Returns a single char (e.g. SKIP_RESULT, FAIL_RESULT,
    PASS_RESULT, NO_DATA_RESULT, etc) that indicates the test modifier
    for the given test_name.
    """
    if test_name not in self._test_results_map:
      return self.__class__.NO_DATA_RESULT

    test_result = self._test_results_map[test_name]
    if test_result.modifier in self.MODIFIER_TO_CHAR.keys():
      return self.MODIFIER_TO_CHAR[test_result.modifier]

    return self.__class__.PASS_RESULT

  def _get_result_char(self, test_name):
    """Returns a single char (e.g. SKIP_RESULT, FAIL_RESULT,
    PASS_RESULT, NO_DATA_RESULT, etc) that indicates the test result
    for the given test_name.
    """
    if test_name not in self._test_results_map:
      return self.__class__.NO_DATA_RESULT

    test_result = self._test_results_map[test_name]
    if test_result.modifier == TestResult.DISABLED:
      return self.__class__.SKIP_RESULT

    if test_result.failed:
      return self.__class__.FAIL_RESULT

    return self.__class__.PASS_RESULT

  def _GetSVNRevision(self, in_directory):
    """Returns the svn revision for the given directory.

    Args:
      in_directory: The directory where svn is to be run.
    """
    # This is overridden in flakiness_dashboard_results_uploader.py.
    raise NotImplementedError()

  def _GetArchivedJSONResults(self):
    """Download JSON file that only contains test
    name list from test-results server. This is for generating incremental
    JSON so the file generated has info for tests that failed before but
    pass or are skipped from current run.

    Returns (archived_results, error) tuple where error is None if results
    were successfully read.
    """
    results_json = {}
    old_results = None
    error = None

    if not self._test_results_server:
      return {}, None

    results_file_url = (self.URL_FOR_TEST_LIST_JSON %
                        (urllib2.quote(self._test_results_server),
                         urllib2.quote(self._builder_name),
                         self.RESULTS_FILENAME,
                         urllib2.quote(self._test_type),
                         urllib2.quote(self._master_name)))

    # pylint: disable=redefined-variable-type
    try:
      # FIXME: We should talk to the network via a Host object.
      results_file = urllib2.urlopen(results_file_url)
      old_results = results_file.read()
    except urllib2.HTTPError as http_error:
      # A non-4xx status code means the bot is hosed for some reason
      # and we can't grab the results.json file off of it.
      if http_error.code < 400 and http_error.code >= 500:
        error = http_error
    except urllib2.URLError as url_error:
      error = url_error
    # pylint: enable=redefined-variable-type

    if old_results:
      # Strip the prefix and suffix so we can get the actual JSON object.
      old_results = StripJSONWrapper(old_results)

      try:
        results_json = json.loads(old_results)
      except Exception: # pylint: disable=broad-except
        _log.debug('results.json was not valid JSON. Clobbering.')
        # The JSON file is not valid JSON. Just clobber the results.
        results_json = {}
    else:
      _log.debug('Old JSON results do not exist. Starting fresh.')
      results_json = {}

    return results_json, error

  def _InsertFailureSummaries(self, results_for_builder):
    """Inserts aggregate pass/failure statistics into the JSON.
    This method reads self._test_results and generates
    FIXABLE, FIXABLE_COUNT and ALL_FIXABLE_COUNT entries.

    Args:
      results_for_builder: Dictionary containing the test results for a
          single builder.
    """
    # Insert the number of tests that failed or skipped.
    fixable_count = len([r for r in self._test_results if r.Fixable()])
    self._InsertItemIntoRawList(results_for_builder,
                                fixable_count, self.FIXABLE_COUNT)

    # Create a test modifiers (FAILS, FLAKY etc) summary dictionary.
    entry = {}
    for test_name in self._test_results_map.iterkeys():
      result_char = self._GetModifierChar(test_name)
      entry[result_char] = entry.get(result_char, 0) + 1

    # Insert the pass/skip/failure summary dictionary.
    self._InsertItemIntoRawList(results_for_builder, entry,
                                self.FIXABLE)

    # Insert the number of all the tests that are supposed to pass.
    all_test_count = len(self._test_results)
    self._InsertItemIntoRawList(results_for_builder,
                                all_test_count, self.ALL_FIXABLE_COUNT)

  def _InsertItemIntoRawList(self, results_for_builder, item, key):
    """Inserts the item into the list with the given key in the results for
    this builder. Creates the list if no such list exists.

    Args:
      results_for_builder: Dictionary containing the test results for a
          single builder.
      item: Number or string to insert into the list.
      key: Key in results_for_builder for the list to insert into.
    """
    if key in results_for_builder:
      raw_list = results_for_builder[key]
    else:
      raw_list = []

    raw_list.insert(0, item)
    raw_list = raw_list[:self.MAX_NUMBER_OF_BUILD_RESULTS_TO_LOG]
    results_for_builder[key] = raw_list

  def _InsertItemRunLengthEncoded(self, item, encoded_results):
    """Inserts the item into the run-length encoded results.

    Args:
      item: String or number to insert.
      encoded_results: run-length encoded results. An array of arrays, e.g.
          [[3,'A'],[1,'Q']] encodes AAAQ.
    """
    if len(encoded_results) and item == encoded_results[0][1]:
      num_results = encoded_results[0][0]
      if num_results <= self.MAX_NUMBER_OF_BUILD_RESULTS_TO_LOG:
        encoded_results[0][0] = num_results + 1
    else:
      # Use a list instead of a class for the run-length encoding since
      # we want the serialized form to be concise.
      encoded_results.insert(0, [1, item])

  def _InsertGenericMetaData(self, results_for_builder):
    """ Inserts generic metadata (such as version number, current time etc)
    into the JSON.

    Args:
      results_for_builder: Dictionary containing the test results for
          a single builder.
    """
    self._InsertItemIntoRawList(results_for_builder,
                                self._build_number, self.BUILD_NUMBERS)

    # Include SVN revisions for the given repositories.
    for (name, path) in self._svn_repositories:
      # Note: for JSON file's backward-compatibility we use 'chrome' rather
      # than 'chromium' here.
      lowercase_name = name.lower()
      if lowercase_name == 'chromium':
        lowercase_name = 'chrome'
      self._InsertItemIntoRawList(results_for_builder,
                                  self._GetSVNRevision(path),
                                  lowercase_name + 'Revision')

    self._InsertItemIntoRawList(results_for_builder,
                                int(time.time()),
                                self.TIME)

  def _InsertTestTimeAndResult(self, test_name, tests):
    """ Insert a test item with its results to the given tests dictionary.

    Args:
      tests: Dictionary containing test result entries.
    """

    result = self._get_result_char(test_name)
    test_time = self._GetTestTiming(test_name)

    this_test = tests
    for segment in test_name.split('/'):
      if segment not in this_test:
        this_test[segment] = {}
      this_test = this_test[segment]

    if not len(this_test):
      self._PopulateResultsAndTimesJSON(this_test)

    if self.RESULTS in this_test:
      self._InsertItemRunLengthEncoded(result, this_test[self.RESULTS])
    else:
      this_test[self.RESULTS] = [[1, result]]

    if self.TIMES in this_test:
      self._InsertItemRunLengthEncoded(test_time, this_test[self.TIMES])
    else:
      this_test[self.TIMES] = [[1, test_time]]

  def _ConvertJSONToCurrentVersion(self, results_json):
    """If the JSON does not match the current version, converts it to the
    current version and adds in the new version number.
    """
    if self.VERSION_KEY in results_json:
      archive_version = results_json[self.VERSION_KEY]
      if archive_version == self.VERSION:
        return
    else:
      archive_version = 3

    # version 3->4
    if archive_version == 3:
      for results in results_json.values():
        self._ConvertTestsToTrie(results)

    results_json[self.VERSION_KEY] = self.VERSION

  def _ConvertTestsToTrie(self, results):
    if not self.TESTS in results:
      return

    test_results = results[self.TESTS]
    test_results_trie = {}
    for test in test_results.iterkeys():
      single_test_result = test_results[test]
      AddPathToTrie(test, single_test_result, test_results_trie)

    results[self.TESTS] = test_results_trie

  def _PopulateResultsAndTimesJSON(self, results_and_times):
    results_and_times[self.RESULTS] = []
    results_and_times[self.TIMES] = []
    return results_and_times

  def _CreateResultsForBuilderJSON(self):
    results_for_builder = {}
    results_for_builder[self.TESTS] = {}
    return results_for_builder

  def _RemoveItemsOverMaxNumberOfBuilds(self, encoded_list):
    """Removes items from the run-length encoded list after the final
    item that exceeds the max number of builds to track.

    Args:
      encoded_results: run-length encoded results. An array of arrays, e.g.
          [[3,'A'],[1,'Q']] encodes AAAQ.
    """
    num_builds = 0
    index = 0
    for result in encoded_list:
      num_builds = num_builds + result[0]
      index = index + 1
      if num_builds > self.MAX_NUMBER_OF_BUILD_RESULTS_TO_LOG:
        return encoded_list[:index]
    return encoded_list

  def _NormalizeResultsJSON(self, test, test_name, tests):
    """ Prune tests where all runs pass or tests that no longer exist and
    truncate all results to maxNumberOfBuilds.

    Args:
      test: ResultsAndTimes object for this test.
      test_name: Name of the test.
      tests: The JSON object with all the test results for this builder.
    """
    test[self.RESULTS] = self._RemoveItemsOverMaxNumberOfBuilds(
        test[self.RESULTS])
    test[self.TIMES] = self._RemoveItemsOverMaxNumberOfBuilds(
        test[self.TIMES])

    is_all_pass = self._IsResultsAllOfType(test[self.RESULTS],
                                           self.PASS_RESULT)
    is_all_no_data = self._IsResultsAllOfType(test[self.RESULTS],
                                              self.NO_DATA_RESULT)
    max_time = max([test_time[1] for test_time in test[self.TIMES]])

    # Remove all passes/no-data from the results to reduce noise and
    # filesize. If a test passes every run, but takes > MIN_TIME to run,
    # don't throw away the data.
    if is_all_no_data or (is_all_pass and max_time <= self.MIN_TIME):
      del tests[test_name]

  # method could be a function pylint: disable=R0201
  def _IsResultsAllOfType(self, results, result_type):
    """Returns whether all the results are of the given type
    (e.g. all passes)."""
    return len(results) == 1 and results[0][1] == result_type


class _FileUploader(object):

  def __init__(self, url, timeout_seconds):
    self._url = url
    self._timeout_seconds = timeout_seconds

  def UploadAsMultipartFormData(self, files, attrs):
    file_objs = []
    for filename, path in files:
      with file(path, 'rb') as fp:
        file_objs.append(('file', filename, fp.read()))

    # FIXME: We should use the same variable names for the formal and actual
    # parameters.
    content_type, data = _EncodeMultipartFormData(attrs, file_objs)
    return self._UploadData(content_type, data)

  def _UploadData(self, content_type, data):
    start = time.time()
    end = start + self._timeout_seconds
    while time.time() < end:
      try:
        request = urllib2.Request(self._url, data,
                                  {'Content-Type': content_type})
        return urllib2.urlopen(request)
      except urllib2.HTTPError as e:
        _log.warn("Received HTTP status %s loading \"%s\".  "
                  'Retrying in 10 seconds...', e.code, e.filename)
        time.sleep(10)


def _GetMIMEType(filename):
  return mimetypes.guess_type(filename)[0] or 'application/octet-stream'


# FIXME: Rather than taking tuples, this function should take more
# structured data.
def _EncodeMultipartFormData(fields, files):
  """Encode form fields for multipart/form-data.

  Args:
    fields: A sequence of (name, value) elements for regular form fields.
    files: A sequence of (name, filename, value) elements for data to be
           uploaded as files.
  Returns:
    (content_type, body) ready for httplib.HTTP instance.

  Source:
    http://code.google.com/p/rietveld/source/browse/trunk/upload.py
  """
  BOUNDARY = '-M-A-G-I-C---B-O-U-N-D-A-R-Y-'
  CRLF = '\r\n'
  lines = []

  for key, value in fields:
    lines.append('--' + BOUNDARY)
    lines.append('Content-Disposition: form-data; name="%s"' % key)
    lines.append('')
    if isinstance(value, unicode):
      value = value.encode('utf-8')
    lines.append(value)

  for key, filename, value in files:
    lines.append('--' + BOUNDARY)
    lines.append('Content-Disposition: form-data; name="%s"; '
                 'filename="%s"' % (key, filename))
    lines.append('Content-Type: %s' % _GetMIMEType(filename))
    lines.append('')
    if isinstance(value, unicode):
      value = value.encode('utf-8')
    lines.append(value)

  lines.append('--' + BOUNDARY + '--')
  lines.append('')
  body = CRLF.join(lines)
  content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
  return content_type, body
