#!/usr/bin/python
#
# Copyright 2014 Google Inc. All Rights Reserved.
import argparse
import os
import re
import shutil
import subprocess
import sys
import zipfile
parser = argparse.ArgumentParser(
    description=('Update prebuilt android build tools'))
parser.add_argument(
    'buildId',
    type=int,
    nargs='?',
    help='Build server build ID')
parser.add_argument(
    '--target',
    default='sdk_phone_mips-sdk',
    help='Download from the specified build server target')
parser.add_argument(
    '--from-local-dir',
    dest='localDir',
    help='Copy prebuilts from local directory instead of buildserver')
parser.add_argument(
    '--no-git',
    action='store_true',
    help='Do not create a git commit for the import')
args = parser.parse_args()
if not args.buildId and not args.localDir:
    parser.error("you must specify either a build ID or --from-local-dir")
    sys.exit(1)
if not args.no_git:
    # Make sure we don't overwrite any pending changes
    try:
        subprocess.check_call(['git', 'diff', '--quiet', '--', '**'])
        subprocess.check_call(['git', 'diff', '--quiet', '--cached', '--', '**'])
    except subprocess.CalledProcessError:
        print >> sys.stderr, "FAIL: There are uncommitted changes here; please revert or stash"
        sys.exit(1)
def GetSSOCmdline(url):
    return ['sso_client', '--location', '--request_timeout', '90', '--url', url]
def SSOFetch(url):
    return subprocess.check_output(GetSSOCmdline(url), stderr=subprocess.STDOUT)
def FetchFile(srcFile, dstFile):
    if not args.localDir:
        fileURL = buildURL + '/' + srcFile
        subprocess.check_call(' '.join(GetSSOCmdline(fileURL) + ['>', dstFile]), shell=True)
    else:
        shutil.copyfile(os.path.join(args.localDir, srcFile), dstFile)
if not args.localDir:
    # to start, find the build server branch we're downloading from
    try:
        branch = SSOFetch("http://android-build/buildbot-update?op=GET-BRANCH&bid=%d" % args.buildId)
    except subprocess.CalledProcessError:
        print >> sys.stderr, "FAIL: Unable to retrieve branch for build ID %d" % args.buildId
        sys.exit(1)
    buildURL = "http://android-build/builds/%s-mac-%s/%d" % (branch, args.target, args.buildId)
    # fetch the list build artifacts
    try:
        listingText = SSOFetch(buildURL + "?output=text")
    except subprocess.CalledProcessError:
        print >> sys.stderr, "FAIL: Unable to retrieve listing for build ID %d" % args.buildId
        sys.exit(1)
    listing = listingText.strip().split('\n')
else:
    listing = os.listdir(args.localDir)
buildToolsZipRE = re.compile(r'^sdk-repo-darwin-build-tools-.*\.zip$')
buildToolsZipFile = None
for fname in listing:
    if buildToolsZipRE.match(fname):
        buildToolsZipFile = fname
        break
if not buildToolsZipFile:
    src = 'directory' if args.localDir else 'build'
    print >> sys.stderr, "FAIL: The specified %s contains no platform ZIP" % src
    sys.exit(1)
try:
    FetchFile(buildToolsZipFile, buildToolsZipFile)
except:
    print >> sys.stderr, "FAIL: Unable to fetch %s" % buildToolsZipFile
    sys.exit(1)
try:    # make sure we delete the downloaded ZIP
    BUILD_TOOLS_DIRS = [
        ('android-5.1/lib', 'lib'),
        ('android-5.1/renderscript', 'renderscript'),
    ]
    executableMap = {}
    with zipfile.ZipFile(buildToolsZipFile) as buildToolsZip:
        files = filter(lambda x: x.count('/') == 1 and not x[-1] == '/', buildToolsZip.namelist())
        for fileEntry in map(lambda x: (x, x[x.find('/')+1:]) , files):
            executable = False
            if os.path.exists(fileEntry[1]):
                if os.path.isdir(fileEntry[1]):
                    subprocess.check_call(['git', 'rm', '-rf', fileEntry[1]])
                else:
                    executable = os.access(fileEntry[1], os.X_OK)
                    subprocess.check_call(['git', 'rm', fileEntry[1]])
            with buildToolsZip.open(fileEntry[0], 'r') as infile:
                with open(fileEntry[1], 'w+') as outfile:
                    shutil.copyfileobj(infile, outfile)
            if executable:
                subprocess.check_call(['chmod', '+x', fileEntry[1]])
            subprocess.check_call(['git', 'add', fileEntry[1]])
        for dirEntry in BUILD_TOOLS_DIRS:
            if os.path.exists(dirEntry[1]):
                if os.path.isdir(dirEntry[1]):
                    subprocess.check_call(['git', 'rm', '-rf', dirEntry[1]])
                else:
                    subprocess.check_call(['git', 'rm', dirEntry[1]])
            # extract the new version of the directory
            fileZipDir = dirEntry[0] + '/'
            for fname in buildToolsZip.namelist():
                if (fname[-1] != '/'
                        and fname.startswith(dirEntry[0])):
                    relativePath = fname[len(fileZipDir):]
                    subdirs = os.path.join(dirEntry[1], os.path.dirname(relativePath))
                    if not os.path.exists(subdirs):
                        os.makedirs(subdirs)
                    with buildToolsZip.open(fname, 'r') as infile:
                        with open(os.path.join(dirEntry[1], relativePath), 'w+') as outfile:
                            shutil.copyfileobj(infile, outfile)
            subprocess.check_call(['git', 'add', dirEntry[1]])
    # modify the source.properties
    subprocess.check_call(['sed', '-i', 's/Pkg.Revision=/\/\/Pkg.Revision=/',
            'source.properties'])
    subprocess.check_call(' '.join(['echo', '-e',
            '"Archive.Os=MACOSX\nPkg.Revision=22.0.0\nArchive.Arch=ANY"'] +
            ['>>', 'source.properties']), shell=True)
    subprocess.check_call(['git', 'add', 'source.properties'])
    if not args.no_git:
        # commit all changes
        if not args.localDir:
            # gather useful info
            buildInfo = dict(
                buildURL = buildURL,
                buildId = args.buildId,
                branch = branch,
                buildToolsZipFile = buildToolsZipFile,
            )
            msg = """Import L Build Tools from {branch} build {buildId}
{buildURL}/{buildToolsZipFile}
source.properties has been modified to make this appear as API 22
""".format(**buildInfo)
        else:
            msg = "DO NOT SUBMIT Import locally built android platform from %s" % args.localDir
        subprocess.check_call(['git', 'commit', '-m', msg])
        print 'Update successful.'
        if not args.localDir:
            print 'Be sure to upload this manually to gerrit.'
finally:
    # revert all stray files, including the downloaded zip
    try:
        with open(os.devnull, 'w') as bitbucket:
            subprocess.check_call(['git', 'add', '-Af', '.'], stdout=bitbucket)
            subprocess.check_call(
                    ['git', 'commit', '-m', 'COMMIT TO REVERT - RESET ME!!!'], stdout=bitbucket)
            subprocess.check_call(['git', 'reset', '--hard', 'HEAD~1'], stdout=bitbucket)
    except subprocess.CalledProcessError:
        print >> sys.stderr, "ERROR: Failed cleaning up, manual cleanup required!!!"

