# 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 that handles the processing of patches to the source tree."""

import constants
import glob
import json
import logging
import os
import re
import shutil
import tempfile

from chromite.lib import cros_build_lib as cros_lib

# The prefix of the temporary directory created to store local patches.
_TRYBOT_TEMP_PREFIX = 'trybot_patch-'

# URL where the Commit Queue documentation is stored.
_PALADIN_DOCUMENTATION_URL = ('http://www.chromium.org/developers/'
                              'tree-sheriffs/sheriff-details-chromium-os/'
                              'commit-queue-overview')


class PatchException(Exception):
  """Exception thrown by GetGerritPatchInfo."""
  pass


class ApplyPatchException(Exception):
  """Exception thrown if we fail to apply a patch."""
  # Types used to denote what we failed to apply against.
  TYPE_REBASE_TO_TOT = 1
  TYPE_REBASE_TO_PATCH_INFLIGHT = 2

  def __init__(self, patch, type=TYPE_REBASE_TO_TOT):
    super(ApplyPatchException, self).__init__()
    self.patch = patch
    self.type = type

  def __str__(self):
    return 'Failed to apply patch ' + str(self.patch)


class MissingChangeIDException(Exception):
  """Raised if a patch is missing a Change-ID."""
  pass


class Patch(object):
  """Abstract class representing a Git Patch."""

  def __init__(self, project, tracking_branch):
    """Initialization of abstract Patch class.

    Args:
      project: The name of the project that the patch applies to.
      tracking_branch:  The remote branch of the project the patch applies to.
    """
    self.project = project
    self.tracking_branch = tracking_branch

  def Apply(self, buildroot, trivial):
    """Applies the patch to specified buildroot. Implement in subclasses.

    Args:
      buildroot:  The buildroot.
      trivial:  Only allow trivial merges when applying change.

    Raises:
      PatchException
    """
    raise NotImplementedError('Applies the patch to specified buildroot.')


class GerritPatch(Patch):
  """Object that represents a Gerrit CL."""
  _PUBLIC_URL = os.path.join(constants.GERRIT_HTTP_URL, 'gerrit/p')
  _GIT_CHANGE_ID_RE = re.compile(r'^\s*Change-Id:\s*(\w+)\s*$', re.MULTILINE)
  _PALADIN_DEPENDENCY_RE = re.compile(r'^\s*CQ-DEPEND=(.*)$', re.MULTILINE)
  _PALADIN_BUG_RE = re.compile('(\w+)')

  def __init__(self, patch_dict, internal):
    """Construct a GerritPatch object from Gerrit query results.

    Gerrit query JSON fields are documented at:
    http://gerrit-documentation.googlecode.com/svn/Documentation/2.2.1/json.html

    Args:
      patch_dict: A dictionary containing the parsed JSON gerrit query results.
      internal: Whether the CL is an internal CL.
    """
    Patch.__init__(self, patch_dict['project'], patch_dict['branch'])
    self.internal = internal
    # id - The CL's ChangeId
    self.id = patch_dict['id']
    # ref - The remote ref that contains the patch.
    self.ref = patch_dict['currentPatchSet']['ref']
    # revision - The CL's SHA1 hash.
    self.revision = patch_dict['currentPatchSet']['revision']
    self.patch_number = patch_dict['currentPatchSet']['number']
    self.commit = patch_dict['currentPatchSet']['revision']
    self.owner, _, _ = patch_dict['owner']['email'].partition('@')
    self.gerrit_number = patch_dict['number']
    self.url = patch_dict['url']
    # status - Current state of this change.  Can be one of
    # ['NEW', 'SUBMITTED', 'MERGED', 'ABANDONED'].
    self.status = patch_dict['status']

  def IsAlreadyMerged(self):
    """Returns whether the patch has already been merged in Gerrit."""
    return self.status == 'MERGED'

  def _GetProjectUrl(self):
    """Returns the url to the gerrit project."""
    if self.internal:
      url_prefix = constants.GERRIT_INT_SSH_URL
    else:
      url_prefix = self._PUBLIC_URL

    return os.path.join(url_prefix, self.project)

  def _RebaseOnto(self, branch, upstream, project_dir, trivial):
    """Attempts to rebase FETCH_HEAD onto branch -- while not on a branch.

    Raises:
      cros_lib.RunCommandError:  If the rebase operation returns an error code.
        In this case, we still rebase --abort before returning.
    """
    try:
      git_rb = ['git', 'rebase']
      if trivial: git_rb.extend(['--strategy', 'resolve', '-X', 'trivial'])
      git_rb.extend(['--onto', branch, upstream, 'FETCH_HEAD'])
      # Run the rebase command.
      cros_lib.RunCommand(git_rb, cwd=project_dir)

    except cros_lib.RunCommandError:
      cros_lib.RunCommand(['git', 'rebase', '--abort'], cwd=project_dir,
                          error_ok=True)
      raise

  def _RebasePatch(self, buildroot, project_dir, trivial):
    """Rebase patch fetched from gerrit onto constants.PATCH_BRANCH.

    When the function completes, the constants.PATCH_BRANCH branch will be
    pointing to the rebased change.

    Arguments:
      buildroot: The buildroot.
      project_dir: Directory of the project that is being patched.
      trivial: Use trivial logic that only allows trivial merges.  Note:
        Requires Git >= 1.7.6 -- bug <.  Bots have 1.7.6 installed.

    Raises:
      ApplyPatchException: If the patch failed to apply.
    """
    url = self._GetProjectUrl()
    upstream = _GetProjectManifestBranch(buildroot, self.project)
    cros_lib.RunCommand(['git', 'fetch', url, self.ref], cwd=project_dir)
    try:
      self._RebaseOnto(constants.PATCH_BRANCH, upstream, project_dir, trivial)
      cros_lib.RunCommand(['git', 'checkout', '-B', constants.PATCH_BRANCH],
                          cwd=project_dir)
    except cros_lib.RunCommandError:
      try:
        # Failed to rebase against branch, try TOT.
        self._RebaseOnto(upstream, upstream, project_dir, trivial)
      except cros_lib.RunCommandError:
        raise ApplyPatchException(
            self, type=ApplyPatchException.TYPE_REBASE_TO_TOT)
      else:
        # We failed to apply to patch_branch but succeeded against TOT.
        # We should pass a different type of exception in this case.
        raise ApplyPatchException(
            self, type=ApplyPatchException.TYPE_REBASE_TO_PATCH_INFLIGHT)

    finally:
      cros_lib.RunCommand(['git', 'checkout', constants.PATCH_BRANCH],
                          cwd=project_dir)

  def Apply(self, buildroot, trivial=False):
    """Implementation of Patch.Apply().

    Raises:
      ApplyPatchException: If the patch failed to apply.
    """
    project_dir = cros_lib.GetProjectDir(buildroot, self.project)
    if not cros_lib.DoesLocalBranchExist(project_dir, constants.PATCH_BRANCH):
      upstream = cros_lib.GetManifestDefaultBranch(buildroot)
      cros_lib.RunCommand(['git', 'checkout', '-b', constants.PATCH_BRANCH,
                           '-t', 'm/' + upstream],
                          cwd=project_dir)
    self._RebasePatch(buildroot, project_dir, trivial)

  # --------------------- Gerrit Operations --------------------------------- #

  @staticmethod
  def _RunCommand(cmd, dryrun):
    """Runs the specified shell cmd if dryrun=False."""
    if dryrun:
      logging.info('Would have run: %s', ' '.join(cmd))
    else:
      cros_lib.RunCommand(cmd, error_ok=True)

  @staticmethod
  def ConstructErrorMessage(msg):
    return msg + (' Please see %s for more information.' %
                  _PALADIN_DOCUMENTATION_URL)

  def HandleCouldNotSubmit(self, helper, build_log, dryrun=False):
    """Handler that is called when the Commit Queue can't submit a change.

    This should be rare, but if an admin overrides the commit queue and commits
    a change that conflicts with this change, it'll apply, build/validate but
    receive an error when submitting.

    Args:
      helper: Instance of gerrit_helper for the gerrit instance.
      dryrun: If true, do not actually commit anything to Gerrit.

    """
    msg = ('The Commit Queue failed to submit your change in %s . '
           'This is most likely due to an owner of your repo overriding the '
           'Commit Queue and committing a change that conflicts with yours. '
           'Please rebase and re-upload your change to re-submit.' % build_log)
    msg = self.ConstructErrorMessage(msg)

    cmd = helper.GetGerritReviewCommand(
        ['-m', '"%s"' % msg, '%s,%s' % (self.gerrit_number, self.patch_number)])
    GerritPatch._RunCommand(cmd, dryrun)
    self.RemoveCommitReady(helper, dryrun)

  def HandleCouldNotVerify(self, helper, build_log, dryrun=False):
    """Handler for when the Commit Queue fails to validate a change.

    This handler notifies set Verified-1 to the review forcing the developer
    to re-upload a change that works.  There are many reasons why this might be
    called e.g. build or testing exception.

    Args:
      helper: Instance of gerrit_helper for the gerrit instance.
      build_log:  URL to the build log where verification results could be
        found.
      dryrun: If true, do not actually commit anything to Gerrit.

    """
    msg = ('The Commit Queue failed to verify your change in %s . '
           'If you believe this happened in error, just re-mark your commit as '
           'ready. Your change will then get automatically retried.' %
           build_log)
    msg = self.ConstructErrorMessage(msg)
    cmd = helper.GetGerritReviewCommand(
        ['-m', '"%s"' % msg, '%s,%s' % (self.gerrit_number, self.patch_number)])
    GerritPatch._RunCommand(cmd, dryrun)
    self.RemoveCommitReady(helper, dryrun)

  def RemoveCommitReady(self, helper, dryrun=False):
    """Remove any commit ready bits associated with CL."""
    query = ['-c',
             '"delete from patch_set_approvals where change_id=%s'
             ' AND category_id=\'COMR\';"' % self.gerrit_number
            ]
    cmd = helper.GetGerritSqlCommand(query)
    GerritPatch._RunCommand(cmd, dryrun)

  def HandleCouldNotApply(self, helper, build_log, dryrun=False):
    """Handler for when the Commit Queue fails to apply a change.

    This handler notifies set CodeReview-2 to the review forcing the developer
    to re-upload a rebased change.

    Args:
      helper: Instance of gerrit_helper for the gerrit instance.
      dryrun: If true, do not actually commit anything to Gerrit.
    """
    msg = ('The Commit Queue failed to apply your change cleanly in %s . '
           'Please re-sync, rebase, and re-upload your change.' % build_log)
    msg = self.ConstructErrorMessage(msg)
    cmd = helper.GetGerritReviewCommand(
        ['-m', '"%s"' % msg, '%s,%s' % (self.gerrit_number, self.patch_number)])
    GerritPatch._RunCommand(cmd, dryrun)
    self.RemoveCommitReady(helper, dryrun)

  def CommitMessage(self, buildroot):
    """Returns the commit message for the patch as a string."""
    url = self._GetProjectUrl()
    project_dir = cros_lib.GetProjectDir(buildroot, self.project)
    cros_lib.RunCommand(['git', 'fetch', url, self.ref], cwd=project_dir)
    return_obj = cros_lib.RunCommand(['git', 'show', '-s', 'FETCH_HEAD'],
                                     cwd=project_dir, redirect_stdout=True)
    return return_obj.output

  def GerritDependencies(self, buildroot):
    """Returns an ordered list of dependencies from Gerrit.

    The list of changes are in order from FETCH_HEAD back to m/master.

    Arguments:
      buildroot: The buildroot.
    Returns:
      An ordered list of Gerrit revisions that this patch depends on.
    Raises:
      MissingChangeIDException: If a dependent change is missing its ChangeID.
    """
    dependencies = []
    url = self._GetProjectUrl()
    project_dir = cros_lib.GetProjectDir(buildroot, self.project)
    cros_lib.RunCommand(['git', 'fetch', url, self.ref], cwd=project_dir)
    return_obj = cros_lib.RunCommand(
        ['git', 'log', '-z', '%s..FETCH_HEAD^' %
          _GetProjectManifestBranch(buildroot, self.project)],
        cwd=project_dir, redirect_stdout=True)

    for patch_output in return_obj.output.split('\0'):
      if not patch_output: continue
      change_id_match = self._GIT_CHANGE_ID_RE.search(patch_output)
      if change_id_match:
        dependencies.append(change_id_match.group(1))
      else:
        raise MissingChangeIDException('Missing Change-Id in %s' % patch_output)

    logging.debug('Found %s Gerrit dependencies for change %s', dependencies,
                  self)
    return dependencies

  def PaladinDependencies(self, buildroot):
    """Returns an ordered list of dependencies based on the Commit Message.

    Parses the Commit message for this change looking for lines that follow
    the format:

    CQ-DEPEND:change_num+ e.g.

    A commit which depends on a couple others.

    BUG=blah
    TEST=blah
    CQ-DEPEND=10001,10002
    """
    dependencies = []
    commit_message = self.CommitMessage(buildroot)
    matches = self._PALADIN_DEPENDENCY_RE.findall(commit_message)
    for match in matches:
      dependencies.extend(self._PALADIN_BUG_RE.findall(match))

    logging.debug('Found %s Paladin dependencies for change %s', dependencies,
                  self)
    return dependencies

  def Submit(self, helper, dryrun=False):
    """Submits patch using Gerrit Review.

    Args:
      helper: Instance of gerrit_helper for the gerrit instance.
      dryrun: If true, do not actually commit anything to Gerrit.
    """
    cmd = helper.GetGerritReviewCommand(['--submit', '%s,%s' % (
        self.gerrit_number, self.patch_number)])

    GerritPatch._RunCommand(cmd, dryrun)

  def __str__(self):
    """Returns custom string to identify this patch."""
    return '%s:%s' % (self.owner, self.gerrit_number)

  # Define methods to use patches in sets.  We uniquely identify patches
  # by Gerrit change numbers.
  def __hash__(self):
    return hash(self.id)

  def __eq__(self, other):
    return self.id == other.id


def RemovePatchRoot(patch_root):
  """Removes the temporary directory storing patches."""
  assert os.path.basename(patch_root).startswith(_TRYBOT_TEMP_PREFIX)
  shutil.rmtree(patch_root)


class LocalPatch(Patch):
  """Object that represents a set of local commits that will be patched."""

  def __init__(self, project, tracking_branch, patch_dir, local_branch):
    """Construct a LocalPatch object.

    Args:
      project: Same as Patch constructor arg.
      tracking_branch: Same as Patch constructor arg.
      patch_dir: The directory where the .patch files are stored.
      local_branch:  The local branch of the project that the patch came from.
    """
    Patch.__init__(self, project, tracking_branch)
    self.patch_dir = patch_dir
    self.local_branch = local_branch

  def _GetFileList(self):
    """Return a list of .patch files in sorted order."""
    file_list = glob.glob(os.path.join(self.patch_dir, '*'))
    file_list.sort()
    return file_list

  def Apply(self, buildroot, trivial=False):
    """Implementation of Patch.Apply().  Does not accept trivial option.

    Raises:
      PatchException if the patch is for the wrong tracking branch.
    """
    assert not trivial, 'Local apply not compatible with trivial set'
    manifest_branch = _GetProjectManifestBranch(buildroot, self.project)
    if self.tracking_branch != manifest_branch:
      raise PatchException('branch %s for project %s is not tracking %s'
                           % (self.local_branch, self.project,
                              manifest_branch))

    project_dir = cros_lib.GetProjectDir(buildroot, self.project)
    try:
      cros_lib.RunCommand(['repo', 'start', constants.PATCH_BRANCH, '.'],
                          cwd=project_dir)
      cros_lib.RunCommand(['git', 'am', '--3way'] + self._GetFileList(),
                          cwd=project_dir)
    except cros_lib.RunCommandError:
      raise ApplyPatchException(self)

  def __str__(self):
    """Returns custom string to identify this patch."""
    return '%s:%s' % (self.project, self.local_branch)


def GetGerritPatchInfo(patches):
  """Query Gerrit server for patch information.

  Args:
    patches: a list of patch ID's to query.  Internal patches start with a '*'.

  Returns:
    A list of GerritPatch objects describing each patch.

  Raises:
    PatchException if a patch can't be found.
  """
  parsed_patches = []
  for patch in patches:
    if patch.startswith('*'):
      # Internal CL's have a '*' in front
      internal = True
      server, port = constants.GERRIT_INT_HOST, constants.GERRIT_INT_PORT
      patch = patch[1:]
    else:
      internal = False
      server, port = constants.GERRIT_HOST, constants.GERRIT_PORT

    cmd = ['ssh', '-p', port, server, 'gerrit', 'query', '--current-patch-set',
           '--format=JSON', patch]

    result = cros_lib.RunCommand(cmd, redirect_stdout=True)
    result_dict = json.loads(result.output.splitlines()[0])
    if 'id' in result_dict:
      parsed_patches.append(GerritPatch(result_dict, internal))
    else:
      raise PatchException('Change-ID %s not found on server %s.'
                           % (patch, server))

  return parsed_patches


def _GetRemoteTrackingBranch(project_dir, branch):
  """Get the remote tracking branch of a local branch.

  Raises:
    cros_lib.NoTrackingBranchException if branch does not track anything.
  """
  (remote, ref) = cros_lib.GetTrackingBranch(branch, project_dir)
  return cros_lib.GetShortBranchName(remote, ref)


def _GetProjectManifestBranch(buildroot, project):
  """Get the branch specified in the manifest for the project."""
  (remote, ref) = cros_lib.GetProjectManifestBranch(buildroot,
                                                    project)
  return cros_lib.GetShortBranchName(remote, ref)


def PrepareLocalPatches(patches, manifest_branch):
  """Finish validation of parameters, and save patches to a temp folder.

  Args:
    patches:  A list of user-specified patches, in project[:branch] form.
    manifest_branch: The manifest branch of the buildroot.

  Raises:
    PatchException if:
      1. The project branch isn't specified and the project isn't on a branch.
      2. The project branch doesn't track a remote branch.
  """
  patch_info = []
  patch_root = tempfile.mkdtemp(prefix=_TRYBOT_TEMP_PREFIX)

  for patch_id in range(0, len(patches)):
    project, branch = patches[patch_id].split(':')
    project_dir = cros_lib.GetProjectDir('.', project)

    patch_dir = os.path.join(patch_root, str(patch_id))
    cmd = ['git', 'format-patch', '%s..%s' % ('m/' + manifest_branch, branch),
           '-o', patch_dir]
    cros_lib.RunCommand(cmd, redirect_stdout=True, cwd=project_dir)
    if not os.listdir(patch_dir):
      raise PatchException('No changes found in %s:%s' % (project, branch))

    # Store remote tracking branch for verification during patch stage.
    try:
      tracking_branch = _GetRemoteTrackingBranch(project_dir, branch)
    except cros_lib.NoTrackingBranchException:
      raise PatchException('%s:%s needs to track a remote branch!'
                           % (project, branch))

    patch_info.append(LocalPatch(project, tracking_branch, patch_dir, branch))

  return patch_info
