#!/usr/bin/env python
# Copyright 2014 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import argparse
import sys

from common_includes import *

CONFIG = {
  BRANCHNAME: "auto-tag-v8",
  PERSISTFILE_BASENAME: "/tmp/v8-auto-tag-tempfile",
  DOT_GIT_LOCATION: ".git",
  VERSION_FILE: "src/version.cc",
}


class Preparation(Step):
  MESSAGE = "Preparation."

  def RunStep(self):
    self.CommonPrepare()
    self.PrepareBranch()
    self.GitCheckout("master")
    self.GitSVNRebase()


class GetTags(Step):
  MESSAGE = "Get all V8 tags."

  def RunStep(self):
    self.GitCreateBranch(self._config[BRANCHNAME])

    # Get remote tags.
    tags = filter(lambda s: re.match(r"^svn/tags/[\d+\.]+$", s),
                  self.GitRemotes())

    # Remove 'svn/tags/' prefix.
    self["tags"] = map(lambda s: s[9:], tags)


class GetOldestUntaggedVersion(Step):
  MESSAGE = "Check if there's a version on bleeding edge without a tag."

  def RunStep(self):
    tags = set(self["tags"])
    self["candidate"] = None
    self["candidate_version"] = None
    self["next"] = None
    self["next_version"] = None

    # Iterate backwards through all automatic version updates.
    for git_hash in self.GitLog(
        format="%H", grep="\\[Auto\\-roll\\] Bump up version to").splitlines():

      # Get the version.
      if not self.GitCheckoutFileSafe(self._config[VERSION_FILE], git_hash):
        continue

      self.ReadAndPersistVersion()
      version = self.ArrayToVersion("")

      # Strip off trailing patch level (tags don't include tag level 0).
      if version.endswith(".0"):
        version = version[:-2]

      # Clean up checked-out version file.
      self.GitCheckoutFileSafe(self._config[VERSION_FILE], "HEAD")

      if version in tags:
        if self["candidate"]:
          # Revision "git_hash" is tagged already and "candidate" was the next
          # newer revision without a tag.
          break
        else:
          print("Stop as %s is the latest version and it has been tagged." %
                version)
          self.CommonCleanup()
          return True
      else:
        # This is the second oldest version without a tag.
        self["next"] = self["candidate"]
        self["next_version"] = self["candidate_version"]

        # This is the oldest version without a tag.
        self["candidate"] = git_hash
        self["candidate_version"] = version

    if not self["candidate"] or not self["candidate_version"]:
      print "Nothing found to tag."
      self.CommonCleanup()
      return True

    print("Candidate for tagging is %s with version %s" %
          (self["candidate"], self["candidate_version"]))


class GetLKGRs(Step):
  MESSAGE = "Get the last lkgrs."

  def RunStep(self):
    revision_url = "https://v8-status.appspot.com/revisions?format=json"
    status_json = self.ReadURL(revision_url, wait_plan=[5, 20])
    self["lkgrs"] = [entry["revision"]
                     for entry in json.loads(status_json) if entry["status"]]


class CalculateTagRevision(Step):
  MESSAGE = "Calculate the revision to tag."

  def LastLKGR(self, min_rev, max_rev):
    """Finds the newest lkgr between min_rev (inclusive) and max_rev
    (exclusive).
    """
    for lkgr in self["lkgrs"]:
      # LKGRs are reverse sorted.
      if int(min_rev) <= int(lkgr) and int(lkgr) < int(max_rev):
        return lkgr
    return None

  def RunStep(self):
    # Get the lkgr after the tag candidate and before the next tag candidate.
    candidate_svn = self.GitSVNFindSVNRev(self["candidate"])
    if self["next"]:
      next_svn = self.GitSVNFindSVNRev(self["next"])
    else:
      # Don't include the version change commit itself if there is no upper
      # limit yet.
      candidate_svn =  str(int(candidate_svn) + 1)
      next_svn = sys.maxint
    lkgr_svn = self.LastLKGR(candidate_svn, next_svn)

    if not lkgr_svn:
      print "There is no lkgr since the candidate version yet."
      self.CommonCleanup()
      return True

    # Let's check if the lkgr is at least three hours old.
    self["lkgr"] = self.GitSVNFindGitHash(lkgr_svn)
    if not self["lkgr"]:
      print "Couldn't find git hash for lkgr %s" % lkgr_svn
      self.CommonCleanup()
      return True

    lkgr_utc_time = int(self.GitLog(n=1, format="%at", git_hash=self["lkgr"]))
    current_utc_time = self._side_effect_handler.GetUTCStamp()

    if current_utc_time < lkgr_utc_time + 10800:
      print "Candidate lkgr %s is too recent for tagging." % lkgr_svn
      self.CommonCleanup()
      return True

    print "Tagging revision %s with %s" % (lkgr_svn, self["candidate_version"])


class MakeTag(Step):
  MESSAGE = "Tag the version."

  def RunStep(self):
    if not self._options.dry_run:
      self.GitReset(self["lkgr"])
      self.GitSVNTag(self["candidate_version"])


class CleanUp(Step):
  MESSAGE = "Clean up."

  def RunStep(self):
    self.CommonCleanup()


class AutoTag(ScriptsBase):
  def _PrepareOptions(self, parser):
    parser.add_argument("--dry_run", help="Don't tag the new version.",
                        default=False, action="store_true")

  def _ProcessOptions(self, options):  # pragma: no cover
    if not options.dry_run and not options.author:
      print "Specify your chromium.org email with -a"
      return False
    options.wait_for_lgtm = False
    options.force_readline_defaults = True
    options.force_upload = True
    return True

  def _Steps(self):
    return [
      Preparation,
      GetTags,
      GetOldestUntaggedVersion,
      GetLKGRs,
      CalculateTagRevision,
      MakeTag,
      CleanUp,
    ]


if __name__ == "__main__":  # pragma: no cover
  sys.exit(AutoTag(CONFIG).Run())
