# Copyright (C) 2008 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import re
import sys

from command import Command
from error import GitError, NoSuchProjectError

CHANGE_RE = re.compile(r'^([1-9][0-9]*)(?:[/\.-]([1-9][0-9]*))?$')


class Download(Command):
  COMMON = True
  helpSummary = "Download and checkout a change"
  helpUsage = """
%prog {[project] change[/patchset]}...
"""
  helpDescription = """
The '%prog' command downloads a change from the review system and
makes it available in your project's local working directory.
If no project is specified try to use current directory as a project.
"""

  def _Options(self, p):
    p.add_option('-b', '--branch',
                 help='create a new branch first')
    p.add_option('-c', '--cherry-pick',
                 dest='cherrypick', action='store_true',
                 help="cherry-pick instead of checkout")
    p.add_option('-x', '--record-origin', action='store_true',
                 help='pass -x when cherry-picking')
    p.add_option('-r', '--revert',
                 dest='revert', action='store_true',
                 help="revert instead of checkout")
    p.add_option('-f', '--ff-only',
                 dest='ffonly', action='store_true',
                 help="force fast-forward merge")

  def _ParseChangeIds(self, args):
    if not args:
      self.Usage()

    to_get = []
    project = None

    for a in args:
      m = CHANGE_RE.match(a)
      if m:
        if not project:
          project = self.GetProjects(".")[0]
          print('Defaulting to cwd project', project.name)
        chg_id = int(m.group(1))
        if m.group(2):
          ps_id = int(m.group(2))
        else:
          ps_id = 1
          refs = 'refs/changes/%2.2d/%d/' % (chg_id % 100, chg_id)
          output = project._LsRemote(refs + '*')
          if output:
            regex = refs + r'(\d+)'
            rcomp = re.compile(regex, re.I)
            for line in output.splitlines():
              match = rcomp.search(line)
              if match:
                ps_id = max(int(match.group(1)), ps_id)
        to_get.append((project, chg_id, ps_id))
      else:
        projects = self.GetProjects([a])
        if len(projects) > 1:
          # If the cwd is one of the projects, assume they want that.
          try:
            project = self.GetProjects('.')[0]
          except NoSuchProjectError:
            project = None
          if project not in projects:
            print('error: %s matches too many projects; please re-run inside '
                  'the project checkout.' % (a,), file=sys.stderr)
            for project in projects:
              print('  %s/ @ %s' % (project.relpath, project.revisionExpr),
                    file=sys.stderr)
            sys.exit(1)
        else:
          project = projects[0]
          print('Defaulting to cwd project', project.name)
    return to_get

  def ValidateOptions(self, opt, args):
    if opt.record_origin:
      if not opt.cherrypick:
        self.OptionParser.error('-x only makes sense with --cherry-pick')

      if opt.ffonly:
        self.OptionParser.error('-x and --ff are mutually exclusive options')

  def Execute(self, opt, args):
    for project, change_id, ps_id in self._ParseChangeIds(args):
      dl = project.DownloadPatchSet(change_id, ps_id)
      if not dl:
        print('[%s] change %d/%d not found'
              % (project.name, change_id, ps_id),
              file=sys.stderr)
        sys.exit(1)

      if not opt.revert and not dl.commits:
        print('[%s] change %d/%d has already been merged'
              % (project.name, change_id, ps_id),
              file=sys.stderr)
        continue

      if len(dl.commits) > 1:
        print('[%s] %d/%d depends on %d unmerged changes:'
              % (project.name, change_id, ps_id, len(dl.commits)),
              file=sys.stderr)
        for c in dl.commits:
          print('  %s' % (c), file=sys.stderr)

      if opt.cherrypick:
        mode = 'cherry-pick'
      elif opt.revert:
        mode = 'revert'
      elif opt.ffonly:
        mode = 'fast-forward merge'
      else:
        mode = 'checkout'

      # We'll combine the branch+checkout operation, but all the rest need a
      # dedicated branch start.
      if opt.branch and mode != 'checkout':
        project.StartBranch(opt.branch)

      try:
        if opt.cherrypick:
          project._CherryPick(dl.commit, ffonly=opt.ffonly,
                              record_origin=opt.record_origin)
        elif opt.revert:
          project._Revert(dl.commit)
        elif opt.ffonly:
          project._FastForward(dl.commit, ffonly=True)
        else:
          if opt.branch:
            project.StartBranch(opt.branch, revision=dl.commit)
          else:
            project._Checkout(dl.commit)

      except GitError:
        print('[%s] Could not complete the %s of %s'
              % (project.name, mode, dl.commit), file=sys.stderr)
        sys.exit(1)
