# 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 constants
from chromite.lib import cidb
from chromite.lib import clactions


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 {}

  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):
    """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}
    self.buildTable.append(row)
    return build_id

  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 = {'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}
    self.failureTable[failure_id] = values
    return failure_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):
    """Gets all the actions for the given changes."""
    clauses = set()
    for change in changes:
      change_source = 'internal' if change.internal else 'external'
      clauses.add((int(change.gerrit_number), change_source))
    values = []
    for row in self.GetActionHistory():
      if (row.change_number, row.change_source) in clauses:
        values.append(row)
    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'])
      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):
    """Gets the slaves of given build."""
    return [self._TrimStatus(b) for b in self.buildTable
            if b['master_build_id'] == master_build_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 GetBuildHistory(self, build_config, num_results,
                      ignore_build_id=None, start_date=None, end_date=None,
                      starting_build_number=None, milestone_version=None):
    """Returns the build history for the given |build_config|."""
    builds = [b for b in self.buildTable
              if b['build_config'] == build_config]
    # Reverse sort as that's what's expected.
    builds = sorted(builds[-num_results:], 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['milestone_version'] == milestone_version]

    return builds

  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
