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

"""Fake CIDB for unit testing."""

from __future__ import print_function

import datetime
import itertools

from chromite.lib import build_requests
from chromite.lib import constants
from chromite.lib import cidb
from chromite.lib import clactions
from chromite.lib import failure_message_lib
from chromite.lib import hwtest_results


class FakeCIDBConnection(object):
  """Fake connection to a Continuous Integration database.

  This class is a partial re-implementation of CIDBConnection, using
  in-memory lists rather than a backing database.
  """

  NUM_RESULTS_NO_LIMIT = -1

  def __init__(self, fake_keyvals=None):
    self.buildTable = []
    self.clActionTable = []
    self.buildStageTable = {}
    self.failureTable = {}
    self.fake_time = None
    self.fake_keyvals = fake_keyvals or {}
    self.buildMessageTable = {}
    self.hwTestResultTable = {}
    self.buildRequestTable = {}

  def _TrimStatus(self, status):
    """Trims a build row to keys that should be returned by GetBuildStatus"""
    return {k: v for (k, v) in status.items()
            if k in cidb.CIDBConnection.BUILD_STATUS_KEYS}

  def SetTime(self, fake_time):
    """Sets a fake time to be retrieved by GetTime.

    Args:
      fake_time: datetime.datetime object.
    """
    self.fake_time = fake_time

  def GetTime(self):
    """Gets the current database time."""
    return self.fake_time or datetime.datetime.now()

  def InsertBuild(self, builder_name, waterfall, build_number,
                  build_config, bot_hostname, master_build_id=None,
                  timeout_seconds=None, status=constants.BUILDER_STATUS_PASSED,
                  important=None, buildbucket_id=None, milestone_version=None,
                  platform_version=None):
    """Insert a build row.

    Note this API slightly differs from cidb as we pass status to avoid having
    to have a later FinishBuild call in testing.
    """
    deadline = None
    if timeout_seconds is not None:
      timediff = datetime.timedelta(seconds=timeout_seconds)
      deadline = datetime.datetime.now() + timediff

    build_id = len(self.buildTable)
    row = {'id': build_id,
           'builder_name': builder_name,
           'buildbot_generation': constants.BUILDBOT_GENERATION,
           'waterfall': waterfall,
           'build_number': build_number,
           'build_config' : build_config,
           'bot_hostname': bot_hostname,
           'start_time': datetime.datetime.now(),
           'master_build_id' : master_build_id,
           'deadline': deadline,
           'status': status,
           'finish_time': datetime.datetime.now(),
           'important': important,
           'buildbucket_id': buildbucket_id,
           'final': False,
           'milestone_version': milestone_version,
           'platform_version': platform_version}
    self.buildTable.append(row)
    return build_id

  def FinishBuild(self, build_id, status=None, summary=None, strict=True):
    """Update the build with finished status."""
    build = self.buildTable[build_id]

    if strict and build['final']:
      return 0

    values = {}
    if status is not None:
      values.update(status=status)
    if summary is not None:
      values.update(summary=summary)

    values.update(finish_time=datetime.datetime.now(), final=True)

    if values:
      build.update(values)
      return 1
    else:
      return 0

  def UpdateMetadata(self, build_id, metadata):
    """See cidb.UpdateMetadata.

    Args:
      build_id: The build to update.
      metadata: A cbuildbot metadata object. Or, a dictionary (note: using
                a dictionary is not supported by the base cidb API, but
                is provided for this fake class for ease of use in test
                set-up code).
    """
    d = metadata if isinstance(metadata, dict) else metadata.GetDict()
    versions = d.get('version') or {}
    self.buildTable[build_id].update(
        {'chrome_version': versions.get('chrome'),
         'milestone_version': versions.get('milestone'),
         'platform_version': versions.get('platform'),
         'full_version': versions.get('full'),
         'sdk_version': d.get('sdk-versions'),
         'toolchain_url': d.get('toolchain-url'),
         'build_type': d.get('build_type'),
         'important': d.get('important')})
    return 1

  def InsertCLActions(self, build_id, cl_actions, timestamp=None):
    """Insert a list of |cl_actions|."""
    if not cl_actions:
      return 0

    rows = []
    for cl_action in cl_actions:
      change_number = int(cl_action.change_number)
      patch_number = int(cl_action.patch_number)
      change_source = cl_action.change_source
      action = cl_action.action
      reason = cl_action.reason
      buildbucket_id = cl_action.buildbucket_id

      timestamp = cl_action.timestamp or timestamp or datetime.datetime.now()

      rows.append({
          'build_id' : build_id,
          'change_source' : change_source,
          'change_number': change_number,
          'patch_number' : patch_number,
          'action' : action,
          'timestamp': timestamp,
          'reason' : reason,
          'buildbucket_id': buildbucket_id})

    self.clActionTable.extend(rows)
    return len(rows)

  def InsertBuildStage(self, build_id, name, board=None,
                       status=constants.BUILDER_STATUS_PLANNED):
    build_stage_id = len(self.buildStageTable)
    row = {'build_id': build_id,
           'name': name,
           'board': board,
           'status': status}
    self.buildStageTable[build_stage_id] = row
    return build_stage_id

  def InsertBoardPerBuild(self, build_id, board):
    # TODO(akeshet): Fill this placeholder.
    pass

  def InsertFailure(self, build_stage_id, exception_type, exception_message,
                    exception_category=constants.EXCEPTION_CATEGORY_UNKNOWN,
                    outer_failure_id=None,
                    extra_info=None):
    failure_id = len(self.failureTable)
    values = {'id': failure_id,
              'build_stage_id': build_stage_id,
              'exception_type': exception_type,
              'exception_message': exception_message,
              'exception_category': exception_category,
              'outer_failure_id': outer_failure_id,
              'extra_info': extra_info,
              'timestamp': None}
    self.failureTable[failure_id] = values
    return failure_id

  def InsertBuildMessage(self, build_id, message_type=None,
                         message_subtype=None, message_value=None, board=None):
    """Insert a build message.

    Args:
      build_id: primary key of build recording this message.
      message_type: Optional str name of message type.
      message_subtype: Optional str name of message subtype.
      message_value: Optional value of message.
      board: Optional str name of the board.

    Returns:
      The build message id (string).
    """
    if message_type:
      message_type = message_type[:240]
    if message_subtype:
      message_subtype = message_subtype[:240]
    if message_value:
      message_value = message_value[:480]
    if board:
      board = board[:240]

    build_message_id = len(self.buildMessageTable)
    values = {'build_id': build_id,
              'message_type': message_type,
              'message_subtype': message_subtype,
              'message_value': message_value,
              'board': board}
    self.buildMessageTable[build_message_id] = values
    return build_message_id

  def InsertHWTestResults(self, hwTestResults):
    """Insert HWTestResults into the hwTestResultTable.

    Args:
      hwTestResults: A list of HWTestResult instances.

    Returns:
      The number of inserted rows.
    """
    result_id = len(self.hwTestResultTable)
    for result in hwTestResults:
      values = {'id': result_id,
                'build_id': result.build_id,
                'test_name': result.test_name,
                'status': result.status}
      self.hwTestResultTable[result_id] = values
      result_id = result_id + 1

    return len(hwTestResults)

  def InsertBuildRequest(self, build_id, request_build_config, request_reason,
                         request_build_args=None, request_buildbucket_id=None,
                         timestamp=None):
    """Insert a build request.

    Args:
      build_id: build_id (int) of the build which sends the request.
      request_build_config: build_config (string) of the requested build.
      request_reason: reason (must be a member of
        build_requests.BUILD_REQUEST_REASONS) of the request.
      request_build_args: build_args (string) of the requested build, default to
        None.
      request_buildbucket_id: buildbucket_id (string) of the requested build,
        default to None.
      timestamp: timestamp of the build request when it's created.

    Returns:
       Integer primary key of the inserted row.
    """
    request_id = len(self.buildRequestTable)

    values = {'id': request_id,
              'build_id': build_id,
              'request_build_config': request_build_config,
              'request_build_args': request_build_args,
              'request_buildbucket_id': request_buildbucket_id,
              'request_reason': request_reason,
              'timestamp': timestamp or datetime.datetime.now()}
    self.buildRequestTable[request_id] = values
    return request_id

  def GetBuildMessages(self, build_id):
    """Get the build messages of the given build id.

    Args:
      build_id: build id (string) of the build to get messages.

    Returns:
      A list of build messages (in the format of dict).
    """
    return [v for v in  self.buildMessageTable.values()
            if v['build_id'] == build_id]

  def StartBuildStage(self, build_stage_id):
    if build_stage_id > len(self.buildStageTable):
      return

    self.buildStageTable[build_stage_id]['status'] = (
        constants.BUILDER_STATUS_INFLIGHT)

  def WaitBuildStage(self, build_stage_id):
    if build_stage_id > len(self.buildStageTable):
      return

    self.buildStageTable[build_stage_id]['status'] = (
        constants.BUILDER_STATUS_WAITING)

  def ExtendDeadline(self, build_id, timeout):
    # No sanity checking in fake object.
    now = datetime.datetime.now()
    timediff = datetime.timedelta(seconds=timeout)
    self.buildStageTable[build_id]['deadline'] = now + timediff

  def FinishBuildStage(self, build_stage_id, status):
    if build_stage_id > len(self.buildStageTable):
      return

    self.buildStageTable[build_stage_id]['status'] = status

  def GetActionsForChanges(self, changes, ignore_patch_number=True,
                           status=None, action=None, start_time=None):
    """Gets all the actions for the given changes.

    Args:
      changes: A list of GerritChangeTuple, GerritPatchTuple or GerritPatch
        specifying the changes to whose actions should be fetched.
      ignore_patch_number: Boolean indicating whether to ignore patch_number of
        the changes. If ignore_patch_number is False, only get the actions with
        matched patch_number. Default to True.
      status: If provided, only return the actions with build is |status| (a
        member of constants.BUILDER_ALL_STATUSES). Default to None.
      action: If provided, only return the actions is |action| (a member of
        constants.CL_ACTIONS). Default to None.
      start_time: If provided, only return the actions with timestamp >=
        start_time. Default to None.

    Returns:
      A list of CLAction instances, in action id order.
    """
    values = []
    for row in self.GetActionHistory():
      if start_time is not None and row.timestamp < start_time:
        continue
      if status is not None and row.status != status:
        continue
      if action is not None and row.action != action:
        continue

      for change in changes:
        change_source = 'internal' if change.internal else 'external'

        if (change_source != row.change_source or
            int(change.gerrit_number) != row.change_number):
          continue
        if (not ignore_patch_number and
            int(change.patch_number) != row.patch_number):
          continue

        values.append(row)
        break

    return values

  def GetActionHistory(self, *args, **kwargs):
    """Get all the actions for all changes."""
    # pylint: disable=W0613
    values = []
    for item, action_id in zip(self.clActionTable, itertools.count()):
      row = (
          action_id,
          item['build_id'],
          item['action'],
          item['reason'],
          self.buildTable[item['build_id']]['build_config'],
          item['change_number'],
          item['patch_number'],
          item['change_source'],
          item['timestamp'],
          item['buildbucket_id'],
          self.buildTable[item['build_id']]['status'])
      values.append(row)

    return clactions.CLActionHistory(clactions.CLAction(*row) for row in values)

  def GetBuildStatus(self, build_id):
    """Gets the status of the build."""
    try:
      return self._TrimStatus(self.buildTable[build_id])
    except IndexError:
      return None

  def GetBuildStatuses(self, build_ids):
    """Gets the status of the builds."""
    return [self._TrimStatus(self.buildTable[x]) for x in build_ids]

  def GetSlaveStatuses(self, master_build_id, buildbucket_ids=None):
    """Gets the slaves of given build."""
    if buildbucket_ids is None:
      return [self._TrimStatus(b) for b in self.buildTable
              if b['master_build_id'] == master_build_id]
    else:
      return [self._TrimStatus(b) for b in self.buildTable
              if b['master_build_id'] == master_build_id and
              b['buildbucket_id'] in buildbucket_ids]

  def GetBuildStage(self, build_stage_id):
    """Get build stage given the build_stage_id.

    Args:
      build_stage_id: The build_stage_id to get the stage.

    Returns:
      A dict prensenting the stage if the build_stage_id exists in
      the buildStageTable; else, None.
    """
    return self.buildStageTable.get(build_stage_id)

  def GetBuildStages(self, build_id):
    """Gets build stages given the build_id"""
    return [self.buildStageTable[_id]
            for _id in self.buildStageTable
            if self.buildStageTable[_id]['build_id'] == build_id]

  def GetSlaveStages(self, master_build_id, buildbucket_ids=None):
    """Get the slave stages of the given build.

    Args:
      master_build_id: The build id (string) of the master build.
      buildbucket_ids: A list of buildbucket ids (strings) of the slaves.

    Returns:
      A list of slave stages (in format of dicts).
    """
    slave_builds = []

    if buildbucket_ids is None:
      slave_builds = {b['id']: b for b in self.buildTable
                      if b['master_build_id'] == master_build_id}
    else:
      slave_builds = {b['id']: b for b in self.buildTable
                      if b['master_build_id'] == master_build_id and
                      b['buildbucket_id'] in buildbucket_ids}

    slave_stages = []
    for _id in self.buildStageTable:
      build_id = self.buildStageTable[_id]['build_id']
      if build_id in slave_builds:
        stage = self.buildStageTable[_id].copy()
        stage['build_config'] = slave_builds[build_id]['build_config']
        slave_stages.append(stage)

    return slave_stages

  def GetBuildHistory(self, build_config, num_results,
                      ignore_build_id=None, start_date=None, end_date=None,
                      starting_build_number=None, milestone_version=None,
                      platform_version=None, final=False):
    """Returns the build history for the given |build_config|."""
    return self.GetBuildsHistory(
        build_config, num_results, ignore_build_id=ignore_build_id,
        start_date=start_date, end_date=end_date,
        starting_build_number=starting_build_number,
        milestone_version=milestone_version, platform_version=platform_version,
        final=final)

  def GetBuildsHistory(self, build_configs, num_results,
                       ignore_build_id=None, start_date=None, end_date=None,
                       starting_build_number=None, milestone_version=None,
                       platform_version=None, final=False):
    """Returns the build history for the given |build_configs|."""
    builds = [b for b in self.buildTable
              if b['build_config'] in build_configs]
    # Reverse sort as that's what's expected.
    builds = sorted(builds, reverse=True)

    # Filter results.
    if ignore_build_id is not None:
      builds = [b for b in builds if b['id'] != ignore_build_id]
    if start_date is not None:
      builds = [b for b in builds
                if b['start_time'].date() >= start_date]
    if end_date is not None:
      builds = [b for b in builds
                if 'finish_time' in b and
                b['finish_time'] and
                b['finish_time'].date() <= end_date]
    if starting_build_number is not None:
      builds = [b for b in builds
                if b['build_number'] >= starting_build_number]
    if milestone_version is not None:
      builds = [b for b in builds
                if b.get('milestone_version') == milestone_version]
    if platform_version is not None:
      builds = [b for b in builds
                if b.get('platform_version') == platform_version]
    if final:
      builds = [b for b in builds
                if b.get('final') is True]

    if num_results != -1:
      return builds[:num_results]
    else:
      return builds

  def GetPlatformVersions(self, build_config, num_results=-1,
                          starting_milestone_version=None):
    """Get the platform versions for a build_config."""
    builds = [b for b in self.buildTable
              if b['build_config'] == build_config]

    if starting_milestone_version is not None:
      builds = [b for b in builds if int(b.get('milestone_version')) >=
                int(starting_milestone_version)]

    versions = [b['platform_version'] for b in builds]

    if num_results != -1:
      return versions[:num_results]
    else:
      return versions

  def GetTimeToDeadline(self, build_id):
    """Gets the time remaining until deadline."""
    now = datetime.datetime.now()
    deadline = self.buildTable[build_id]['deadline']
    return max(0, (deadline - now).total_seconds())

  def GetKeyVals(self):
    """Gets contents of keyvalTable."""
    return self.fake_keyvals

  def GetBuildStatusWithBuildbucketId(self, buildbucket_id):
    for row in self.buildTable:
      if row['buildbucket_id'] == buildbucket_id:
        return self._TrimStatus(row)

    return None

  def GetBuildsFailures(self, build_ids):
    """Gets the failure entries for all listed build_ids.

    Args:
      build_ids: list of build ids of the builds to fetch failures for.

    Returns:
      A list of failure_message_lib.StageFailure instances.
    """
    stage_failures = []
    for build_id in build_ids:
      b_dict = self.buildTable[build_id]
      bs_table = {k: v for k, v in self.buildStageTable.iteritems()
                  if v['build_id'] == build_id}

      for f_dict in self.failureTable.values():
        if f_dict['build_stage_id'] in bs_table:
          bs_dict = bs_table[f_dict['build_stage_id']]
          stage_failures.append(
              failure_message_lib.StageFailure.GetStageFailureFromDicts(
                  f_dict, bs_dict, b_dict))

    return stage_failures

  def GetHWTestResultsForBuilds(self, build_ids):
    """Get hwTestResults for builds.

    Args:
      build_ids: A list of build_id (strings) of build.

    Returns:
      A list of hwtest_results.HWTestResult instances.
    """
    results = []
    for value in self.hwTestResultTable.values():
      if value['build_id'] in build_ids:
        results.append(hwtest_results.HWTestResult(
            value['id'], value['build_id'], value['test_name'],
            value['status']))

    return results

  def GetBuildRequestsForBuildConfig(self, request_build_config,
                                     num_results=-1, start_time=None):
    """Get BuildRequests for a build_config.

    Args:
      request_build_config: build config (string) to request.
      num_results: number of results to return, default to -1.
      start_time: get build requests sent after start_time.

    Returns:
      A list of BuildRequest instances sorted by id in descending order.
    """
    return self.GetBuildRequestsForBuildConfigs(
        [request_build_config], num_results=num_results, start_time=start_time)

  def GetBuildRequestsForBuildConfigs(self, request_build_configs,
                                      num_results=-1, start_time=None):
    """Get BuildRequests for a list build_configs.

    Args:
      request_build_configs: build configs (string) to request.
      num_results: number of results to return, default to -1.
      start_time: get build requests sent after start_time.

    Returns:
      A list of BuildRequest instances sorted by id in descending order.
    """
    results = []
    for value in self.buildRequestTable.values():

      if start_time is not None and value['timestamp'] < start_time:
        continue

      if value['request_build_config'] in request_build_configs:
        results.append(build_requests.BuildRequest(
            value['id'], value['build_id'], value['request_build_config'],
            value['request_build_args'], value['request_buildbucket_id'],
            value['request_reason'], value['timestamp']))

    requests = sorted(results, key=lambda r: r.id, reverse=True)

    if num_results != -1:
      return requests[:num_results]
    else:
      return requests

  def HasFailureMsgForStage(self, build_stage_id):
    """Determine whether a build stage has failure messages in failureTable.

    Args:
      build_stage_id: The id of the build_stage to query for.

    Returns:
      True if there're failures reported to failureTable for this build stage
      to cidb; else, False.
    """
    stages = self.failureTable.values()
    for stage in stages:
      if stage['build_stage_id'] == build_stage_id:
        return True

    return False
