# Copyright (c) 2011 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.

"""Module containing helper class and methods for interacting with Gerrit."""

import constants
import json
import logging
import os

from chromite.buildbot import patch as cros_patch
from chromite.lib import cros_build_lib


class GerritHelper():
  """Helper class to manage interaction with Gerrit server."""
  def __init__(self, internal):
    """Initializes variables for interaction with a gerrit server."""
    if internal:
      ssh_port = constants.GERRIT_INT_PORT
      ssh_host = constants.GERRIT_INT_HOST
    else:
      ssh_port = constants.GERRIT_PORT
      ssh_host = constants.GERRIT_HOST

    self.internal = internal
    self.ssh_prefix = ['ssh', '-p', ssh_port, ssh_host]

  def GetGerritQueryCommand(self, query_list):
    """Returns array corresponding to Gerrit Query command.

    Query is useful for getting information about changelists.  Returns results
    in json format for easy dictionary parsing.  Pass in |query| as the query
    args.
    """
    assert isinstance(query_list, list), 'Query command must be list.'
    return self.ssh_prefix + ['gerrit', 'query', '--format=json'] + query_list

  def GetGerritSqlCommand(self, command_list):
    """Returns array corresponding to Gerrit Review command.

    Review can be used to modify a changelist.  Specifically it can change
    scores, abandon, restore or submit it.  Pass in |command|.
    """
    assert isinstance(command_list, list), 'Sql command must be list.'
    return self.ssh_prefix + ['gerrit', 'gsql'] + command_list

  def GetGerritReviewCommand(self, command_list):
    """Returns array corresponding to Gerrit Review command.

    Review can be used to modify a changelist.  Specifically it can change
    scores, abandon, restore or submit it.  Pass in |command|.
    """
    assert isinstance(command_list, list), 'Review command must be list.'
    return self.ssh_prefix + ['gerrit', 'review'] + command_list


  def GrabChangesReadyForCommit(self, branch):
    """Returns the list of changes to try.

    This methods returns a a list of GerritPatch's to try.
    """
    query_string = ('status:open AND CodeReview=+2 AND Verified=+1 '
                    'AND CommitReady=+1 '
                    'AND NOT CodeReview=-2 AND NOT Verified=-1')

    ready_for_commit = ['--current-patch-set', '"%s"' % query_string]

    query_cmd = self.GetGerritQueryCommand(ready_for_commit)
    raw_results = cros_build_lib.RunCommand(query_cmd,
                                            redirect_stdout=True)

    # Each line returned is a json dict.
    changes_to_commit = []
    for raw_result in raw_results.output.splitlines():
      result_dict = json.loads(raw_result)
      if not 'id' in result_dict:
        logging.debug('No change number found in %s' % result_dict)
        continue

      changes_to_commit.append(cros_patch.GerritPatch(result_dict,
                                                      self.internal))

    # Change to commit are ordered in descending order by last update.
    # To be fair it makes sense to do apply changes eldest to newest.
    changes_to_commit.reverse()
    return changes_to_commit

  def GrabPatchFromGerrit(self, project, change, commit):
    """Returns the GerritChange described by the arguments.

    Args:
      project: Name of the Gerrit project for the change.
      change:  The change ID for the change.
      commit:  The specific commit hash for the patch from the review.
    """
    grab_change = (
        ['--current-patch-set',
         '"project:%(project)s AND change:%(change)s AND commit:%(commit)s"' %
             {'project': project, 'change': change, 'commit': commit}
        ])

    query_cmd = self.GetGerritQueryCommand(grab_change)
    raw_results = cros_build_lib.RunCommand(query_cmd,
                                            redirect_stdout=True)

    # First line returned is the json.
    raw_result = raw_results.output.splitlines()[0]
    result_dict = json.loads(raw_result)
    assert result_dict.get('id'), 'Code Review json missing change-id!'
    return cros_patch.GerritPatch(result_dict, self.internal)

  def FilterProjectsNotInSourceTree(self, changes, buildroot):
    """Returns new filtered set of relevant changes to this source checkout.

    There may be many miscellaneous reviews in other Gerrit repos that are not
    part of the checked out manifest.  This method returns a filtered list of
    changes with such reviews removed.

    Args:
      changes:  List of GerritPatch objects.
      buildroot:  Buildroot containing manifest to filter against.

    Returns filtered list of GerritPatch objects.
    """
    manifest_path = os.path.join(buildroot, '.repo', 'manifests/full.xml')
    handler = cros_build_lib.ManifestHandler.ParseManifest(manifest_path)
    projects = handler.projects

    changes_to_return = []
    for change in changes:
      project = projects.get(change.project)
      if project:
        branch = project.get('revision') or handler.default.get('revision')
        patch_branch = 'refs/heads/%s' % change.tracking_branch
        if branch == patch_branch:
          changes_to_return.append(change)
          continue

      logging.info('Filtered change %s', change)

    return changes_to_return

  def IsRevisionCommitted(self, project, revision):
    """Checks to see whether a revision is committed."""
    rev_cmd = self.GetGerritQueryCommand(['project:%s' % project,
                                          'commit:%s' % revision])
    raw_results = cros_build_lib.RunCommand(rev_cmd, redirect_stdout=True)
    result_dict = json.loads(raw_results.output.splitlines()[0])
    return result_dict['status'] not in ['NEW', 'ABANDONED']
