#!/usr/bin/env python2.5
#
# Copyright 2007 Google Inc.
#
# 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 getpass
import logging
import optparse
import os
import subprocess
import sys
from tempfile import mkstemp

from codereview.proto_client import HttpRpc, Proxy
from codereview.review_pb2 import ReviewService_Stub
from codereview.upload_bundle_pb2 import *

try:
  import readline
except ImportError:
  pass

MAX_SEGMENT_SIZE = 1020 * 1024

# The logging verbosity:
#  0: Errors only.
#  1: Status messages.
#  2: Info logs.
#  3: Debug logs.
verbosity = 1

def StatusUpdate(msg):
  """Print a status message to stdout.

  If 'verbosity' is greater than 0, print the message.

  Args:
    msg: The string to print.
  """
  if verbosity > 0:
    print msg


def ErrorExit(msg):
  """Print an error message to stderr and exit."""
  print >>sys.stderr, msg
  sys.exit(1)


def RunShell(command, args=(), silent_ok=False):
  command = "%s %s" % (command, " ".join(args))
  logging.info("Running %s", command)
  stream = os.popen(command, "r")
  data = stream.read()
  if stream.close():
    ErrorExit("Got error status from %s" % command)
  if not silent_ok and not data:
    ErrorExit("No output from %s" % command)
  return data


def RunGit(*args):
  argv = ["git"]
  argv += args
  retcode = subprocess.call(argv)
  if retcode != 0:
    raise OSError, retcode

def GitVal(*args):
  data = RunShell("git", args)
  if data.rfind("\n") == len(data) - 1:
    return data[0 : len(data) - 1]
  return data


parser = optparse.OptionParser(usage="%prog [options] [-- diff_options]")

# Logging
group = parser.add_option_group("Logging options")
group.add_option("-q", "--quiet", action="store_const", const=0,
                 dest="verbose", help="Print errors only.")
group.add_option("-v", "--verbose", action="store_const", const=2,
                 dest="verbose", default=1,
                 help="Print info level logs (default).")
group.add_option("--noisy", action="store_const", const=3,
                 dest="verbose", help="Print all logs.")

# Review server
group = parser.add_option_group("Review server options")
group.add_option("-s", "--server", action="store", dest="server",
                 default="codereview.appspot.com",
                 metavar="SERVER",
                 help=("The server to upload to. The format is host[:port]. "
                       "Defaults to 'codereview.appspot.com'."))
group.add_option("-e", "--email", action="store", dest="email",
                 metavar="EMAIL", default=None,
                 help="The username to use. Will prompt if omitted.")
group.add_option("-H", "--host", action="store", dest="host",
                 metavar="HOST", default=None,
                 help="Overrides the Host header sent with all RPCs.")
group.add_option("--no_cookies", action="store_false",
                 dest="save_cookies", default=True,
                 help="Do not save authentication cookies to local disk.")

# Git
group = parser.add_option_group("Git options")
group.add_option("-p", "--project", action="store", dest="dest_project",
                 metavar="PROJECT",
                 help=("Name of the Git repository to submit into."))
group.add_option("-b", "--branch", action="store", dest="dest_branch",
                 metavar="BRANCH",
                 help=("Name of the branch the changes are proposed for."))
group.add_option("-B", "--base", action="store", dest="base_commit",
                 default="refs/remotes/origin/master",
                 metavar="COMMIT",
                 help=("Base commit for the bundle."))

def GetRpcServer(options):
  """Returns an RpcServer.

  Returns:
    A new RpcServer, on which RPC calls can be made.
  """

  def GetUserCredentials():
    """Prompts the user for a username and password."""
    email = options.email
    if email is None:
      email = raw_input("Email: ").strip()
    password = getpass.getpass("Password for %s: " % email)
    return (email, password)

  # If this is the dev_appserver, use fake authentication.
  host = (options.host or options.server).lower()
  if host == "localhost" or host.startswith("localhost:"):
    email = options.email
    if email is None:
      email = "test@example.com"
      logging.info("Using debug user %s.  Override with --email" % email)

    server = HttpRpc(
        options.server,
        lambda: (email, "password"),
        host_override=options.host,
        extra_headers={"Cookie":
                       'dev_appserver_login="%s:False"' % email})
    # Don't try to talk to ClientLogin.
    server.authenticated = True
    return server

  if options.save_cookies:
    cookie_file = ".gerrit_cookies"
  else:
    cookie_file = None

  return HttpRpc(options.server, GetUserCredentials,
                 host_override=options.host,
                 cookie_file=cookie_file)


def RealMain(argv, data=None):
  logging.basicConfig(format=("%(asctime).19s %(levelname)s %(filename)s:"
                              "%(lineno)s %(message)s "))
  os.environ['LC_ALL'] = 'C'
  options, args = parser.parse_args(argv[1:])

  global verbosity
  verbosity = options.verbose
  if verbosity >= 3:
    logging.getLogger().setLevel(logging.DEBUG)
  elif verbosity >= 2:
    logging.getLogger().setLevel(logging.INFO)

  srv = GetRpcServer(options)
  review = Proxy(ReviewService_Stub(srv))

  git_dir = GitVal("rev-parse","--git-dir")

  revlist = GitVal("rev-list",
                   "^" + options.base_commit,
                   "HEAD").split("\n")

  tmp_fd, tmp_bundle = mkstemp(".bundle", ".gpq", git_dir)
  os.close(tmp_fd)

  try:
    RunGit("bundle", "create",
           tmp_bundle,
           "^" + options.base_commit,
           "HEAD")
    fd = open(tmp_bundle, "rb")

    bundle_id = None
    segment_id = 0
    next_data = fd.read(MAX_SEGMENT_SIZE)

    while len(next_data) > 0:
      this_data = next_data
      next_data = fd.read(MAX_SEGMENT_SIZE)
      segment_id += 1
    
      if bundle_id is None:
        req = UploadBundleRequest()
        req.dest_project = options.dest_project
        req.dest_branch = options.dest_branch
        for c in revlist:
          req.contained_object.append(c)
      else:
        req = UploadBundleContinue()
        req.bundle_id = bundle_id
        req.segment_id = segment_id

      req.bundle_data = this_data
      if len(next_data) > 0:
        req.partial_upload = True
      else:
        req.partial_upload = False

      if bundle_id is None:
        rsp = review.UploadBundle(req)
      else:
        rsp = review.ContinueBundle(req)

      if rsp.status_code == UploadBundleResponse.CONTINUE:
        bundle_id = rsp.bundle_id
      else:
        print rsp
        break
  finally:
    os.unlink(tmp_bundle)

def main():
  try:
    RealMain(sys.argv)
  except KeyboardInterrupt:
    print
    StatusUpdate("Interrupted.")
    sys.exit(1)


if __name__ == "__main__":
  main()
