#!/usr/bin/env python
#
# Copyright (C) 2018 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.
#
# pylint: disable=relative-import

"""Update the prebuilt lldb from the build server."""

import argparse
import inspect
import logging
import os
import shutil
import subprocess
import sys
import utils

def logger():
    """Returns the module level logger."""
    return logging.getLogger(__name__)


def unchecked_call(cmd, *args, **kwargs):
    """subprocess.call with logging."""
    logger().info('unchecked_call: %s', subprocess.list2cmdline(cmd))
    return subprocess.call(cmd, *args, **kwargs)


def check_call(cmd, *args, **kwargs):
    """subprocess.check_call with logging."""
    logger().info('check_call: %s', subprocess.list2cmdline(cmd))
    subprocess.check_call(cmd, *args, **kwargs)


class ArgParser(argparse.ArgumentParser):
    def __init__(self):
        super(ArgParser, self).__init__(
            description=inspect.getdoc(sys.modules[__name__]))

        self.add_argument(
            'build', metavar='BUILD',
            help='Build number to pull from the build server.')

        self.add_argument(
            '-b', '--bug', type=int,
            help='Bug to reference in commit message.')

        self.add_argument(
            '--use-current-branch', action='store_true',
            help='Do not repo start a new branch for the update.')

        self.add_argument(
            '--skip-fetch',
            '-sf',
            action='store_true',
            default=False,
            help='Skip the fetch, and only do the extraction step')

        self.add_argument(
            '--skip-cleanup',
            '-sc',
            action='store_true',
            default=False,
            help='Skip the cleanup, and leave intermediate files')


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


def get_lldb_package(target, build_number):
    return 'lldb-{}-{}.zip'.format(target[1], build_number)


def get_android_package(build_number):
    return 'lldb-android-{}.zip'.format(build_number)


def get_manifest(build_number):
    return 'manifest_{}.xml'.format(build_number)


def extract_package(package, install_dir):
    cmd = ['unzip', package, '-d', install_dir]
    check_call(cmd)


def update_lldb(target, build_number, use_current_branch, download_dir, bug):
    prebuilt_dir = utils.android_path('prebuilts/clang/host',
                                      target[1] + '-x86')
    os.chdir(prebuilt_dir)
    install_subdir = os.path.join(prebuilt_dir, 'lldb')

    if not use_current_branch:
        branch_name = 'update-lldb-{}'.format(build_number)
        unchecked_call(
            ['repo', 'abandon', branch_name, '.'])
        check_call(
            ['repo', 'start', branch_name, '.'])

    package = os.path.join(download_dir, get_lldb_package(target, build_number))
    if os.path.isdir(install_subdir):
        shutil.rmtree(install_subdir)
    os.makedirs(install_subdir)
    extract_package(package, install_subdir)

    android_package = os.path.join(download_dir,
                                   get_android_package(build_number))
    android_dir = os.path.join(install_subdir, "android")
    os.makedirs(android_dir)
    extract_package(android_package, android_dir)

    manifest = os.path.join(download_dir, get_manifest(build_number))
    shutil.copy(manifest, install_subdir)

    check_call(['git', 'add', install_subdir])

    # If there is no difference with the new files, we are already done.
    diff = unchecked_call(['git', 'diff', '--cached', '--quiet'])
    if diff == 0:
        logger().info('Bypassed commit with no diff')
        return

    message_lines = [
        'Update prebuilt LLDB to build {}.'.format(build_number),
    ]
    if bug is not None:
        message_lines.append('')
        message_lines.append('Bug: http://b/{}'.format(bug))
    message_lines.append('Test: N/A')
    message = '\n'.join(message_lines)
    check_call(['git', 'commit', '-m', message])


def fetch(targets, build_number):
    branch = 'git_lldb-master-dev'
    fetch_artifact(branch, targets[0][0], build_number,
                   get_android_package(build_number))
    for target in targets:
        fetch_artifact(branch, target[0], build_number,
                       get_manifest(build_number))
        fetch_artifact(branch, target[0], build_number,
                       get_lldb_package(target, build_number))


def main():
    args = ArgParser().parse_args()
    logging.basicConfig(level=logging.INFO)

    do_fetch = not args.skip_fetch
    do_cleanup = not args.skip_cleanup

    download_dir = os.path.realpath('.download')
    if do_fetch:
        if os.path.isdir(download_dir):
            shutil.rmtree(download_dir)
        os.makedirs(download_dir)

    os.chdir(download_dir)

    targets = [['lldb', 'linux']]
    try:
        if do_fetch:
            fetch(targets, args.build)

        for target in targets:
            update_lldb(target, args.build, args.use_current_branch,
                        download_dir, args.bug)
    finally:
        if do_cleanup:
            shutil.rmtree(download_dir)

    return 0


if __name__ == '__main__':
    main()
