#!/usr/bin/python
"""
Background daemon to refresh OAuth access tokens.
Tokens are written to ~/.git-credential-cache/cookie
Git config variable http.cookiefile is updated.

Runs only on Google Compute Engine.
"""

import atexit
import contextlib
import cookielib
import json
import os
import subprocess
import sys
import time
import urllib2

REFRESH = 25  # seconds remaining when starting refresh
RETRY_INTERVAL = 5 # seconds between retrying a failed refresh

A = 'http://metadata/0.1/meta-data/service-accounts/default/acquire'
S = 'https://www.googleapis.com/auth/gerritcodereview'
COOKIE_JAR = None

def configure_git():
  global COOKIE_JAR

  dir = os.path.join(os.environ['HOME'], '.git-credential-cache')
  COOKIE_JAR = os.path.join(dir, 'cookie')

  if os.path.exists(dir):
    os.chmod(dir, 0700)
  else:
    os.mkdir(dir, 0700)
  subprocess.call([
    'git', 'config', '--global',
    'http.cookiefile', COOKIE_JAR
  ])

def acquire_token(retry):
  while True:
    try:
      with contextlib.closing(urllib2.urlopen(A + '?scopes=' + S)) as token:
        return json.load(token)
    except urllib2.URLError:
      if not retry:
        raise
    time.sleep(RETRY_INTERVAL)

def update_cookie(retry):
  token = acquire_token(retry)
  expires = token['expiresAt']

  tmp_jar = COOKIE_JAR + '.lock'
  cj = cookielib.MozillaCookieJar(tmp_jar)
  cj.set_cookie(cookielib.Cookie(
    version = 0,
    name = 'o',
    value = token['accessToken'],
    port = None,
    port_specified = False,
    domain = '.googlesource.com',
    domain_specified = True,
    domain_initial_dot = True,
    path = '/',
    path_specified = True,
    secure = True,
    expires = expires,
    discard = False,
    comment = None,
    comment_url = None,
    rest = None))
  cj.save()
  os.rename(tmp_jar, COOKIE_JAR)
  return expires

def cleanup():
  if COOKIE_JAR:
    for p in [COOKIE_JAR, COOKIE_JAR + '.lock']:
      if os.path.exists(p):
        os.remove(p)

def refresh_loop(expires):
  atexit.register(cleanup)
  expires = expires - REFRESH
  while True:
    now = time.time()
    expires = max(expires, now + RETRY_INTERVAL)
    while now < expires:
      time.sleep(expires - now)
      now = time.time()
    expires = update_cookie(retry=True) - REFRESH

def main():
  configure_git()
  expires = update_cookie(retry=False)

  if '--nofork' not in sys.argv:
    if os.fork() > 0:
      sys.exit(0)

    os.chdir('/')
    os.setsid()
    os.umask(0)

    pid = os.fork()
    if pid > 0:
      print '%s PID %d' % (sys.argv[0], pid)
      sys.exit(0)

  refresh_loop(expires)

if __name__ == '__main__':
  main()
