#!/usr/bin/env python
#
# Copyright (C) 2016 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 argparse
import glob
import logging
import os
import shutil
import subprocess
import textwrap


THIS_DIR = os.path.realpath(os.path.dirname(__file__))


def logger():
    return logging.getLogger(__name__)


def check_call(cmd):
    logger().debug('Running `%s`', ' '.join(cmd))
    subprocess.check_call(cmd)


def fetch_artifact(branch, build, pattern):
    fetch_artifact_path = '/google/data/ro/projects/android/fetch_artifact'
    cmd = [fetch_artifact_path, '--branch', branch, '--target=linux',
           '--bid', build, pattern]
    check_call(cmd)


def api_str(api_level):
    return 'android-{}'.format(api_level)


def start_branch(build):
    branch_name = 'update-' + (build or 'latest')
    logger().info('Creating branch %s', branch_name)
    check_call(['repo', 'start', branch_name, '.'])


def remove_old_release(install_dir):
    if os.path.exists(os.path.join(install_dir, '.git')):
        logger().info('Removing old install directory "%s"', install_dir)
        check_call(['git', 'rm', '-rf', install_dir])

    # Need to check again because git won't remove directories if they have
    # non-git files in them.
    if os.path.exists(install_dir):
        shutil.rmtree(install_dir)


def install_new_release(branch, build, install_dir):
    os.makedirs(install_dir)

    artifact_pattern = 'android-ndk-*.tar.bz2'
    logger().info('Fetching %s from %s (artifacts matching %s)', build, branch,
                  artifact_pattern)
    fetch_artifact(branch, build, artifact_pattern)
    artifacts = glob.glob('android-ndk-*.tar.bz2')
    try:
        assert len(artifacts) == 1
        artifact = artifacts[0]

        logger().info('Extracting release')
        cmd = ['tar', 'xf', artifact, '-C', install_dir, '--wildcards',
               '--strip-components=1', '*/platforms', '*/sources',
               '*/source.properties']
        check_call(cmd)
    finally:
        for artifact in artifacts:
            os.unlink(artifact)


def symlink_gaps(first, last):
    for api in xrange(first, last + 1):
        if os.path.exists(api_str(api)):
            continue

        # Not all API levels have a platform directory. Make a symlink to the
        # previous API level. For example, symlink android-10 to android-9.
        assert api != 9
        os.symlink(api_str(api - 1), api_str(api))


def make_symlinks(install_dir):
    old_dir = os.getcwd()
    os.chdir(os.path.join(THIS_DIR, install_dir, 'platforms'))

    first_api = 9
    first_lp64_api = 21
    latest_api = 23

    for api in xrange(first_api, first_lp64_api):
        if not os.path.exists(api_str(api)):
            continue

        for arch in ('arch-arm64', 'arch-mips64', 'arch-x86_64'):
            src = os.path.join('..', api_str(first_lp64_api), arch)
            dst = os.path.join(api_str(api), arch)
            if os.path.islink(dst):
                os.unlink(dst)
            os.symlink(src, dst)

    symlink_gaps(first_api, latest_api)
    os.chdir(old_dir)


def commit(branch, build, install_dir):
    logger().info('Making commit')
    check_call(['git', 'add', install_dir])
    message = textwrap.dedent("""\
        Update NDK prebuilts to build {build}.

        Taken from branch {branch}.""").format(branch=branch, build=build)
    check_call(['git', 'commit', '-m', message])


def get_args():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '-b', '--branch', default='master-ndk',
        help='Branch to pull build from.')
    parser.add_argument(
        'major_release', help='Major release being installed, e.g. "r11".')
    parser.add_argument('--build', required=True, help='Build number to pull.')
    parser.add_argument(
        '--use-current-branch', action='store_true',
        help='Perform the update in the current branch. Do not repo start.')
    parser.add_argument(
        '-v', '--verbose', action='count', help='Increase output verbosity.')
    return parser.parse_args()


def main():
    os.chdir(THIS_DIR)

    args = get_args()
    verbose_map = (logging.WARNING, logging.INFO, logging.DEBUG)
    verbosity = args.verbose
    if verbosity > 2:
        verbosity = 2
    logging.basicConfig(level=verbose_map[verbosity])

    install_dir = os.path.realpath(args.major_release)

    if not args.use_current_branch:
        start_branch(args.build)
    remove_old_release(install_dir)
    install_new_release(args.branch, args.build, install_dir)
    make_symlinks(install_dir)
    commit(args.branch, args.build, install_dir)


if __name__ == '__main__':
    main()
