#!/usr/bin/env python
# utils/update-checkout - Utility to update your local checkouts -*- python -*-
#
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See http://swift.org/LICENSE.txt for license information
# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors

from __future__ import print_function

import argparse
import json
import os
import re
import sys


from functools import reduce

sys.path.append(os.path.dirname(__file__))

from SwiftBuildSupport import (
    SWIFT_SOURCE_ROOT,
)  # noqa (E402 module level import not at top of file)

SCRIPT_FILE = os.path.abspath(__file__)
SCRIPT_DIR = os.path.dirname(SCRIPT_FILE)

sys.path.append(os.path.join(SCRIPT_DIR, 'swift_build_support'))

from swift_build_support import shell  # noqa (E402)


def update_single_repository(repo_path, branch, reset_to_remote, should_clean,
                             cross_repo):
    if not os.path.isdir(repo_path):
        return

    print("--- Updating '" + repo_path + "' ---")
    with shell.pushd(repo_path, dry_run=False, echo=False):
        shell.call(["git", "fetch", "--recurse-submodules=yes"], echo=True)

        if should_clean:
            shell.call(['git', 'clean', '-fdx'],
                       echo=True)
            shell.call(['git', 'submodule', 'foreach', '--recursive', 'git',
                        'clean', '-fdx'], echo=True)
            shell.call(['git', 'submodule', 'foreach', '--recursive', 'git',
                        'reset', '--hard', 'HEAD'], echo=True)
            status = shell.call(['git', 'reset', '--hard', 'HEAD'],
                                echo=True)
            if status:
                print("Please, commit your changes.")
                print(status)
                exit(1)

        if branch:
            status = shell.capture(['git', 'status', '--porcelain', '-uno'],
                                   echo=False)
            if status:
                print("Please, commit your changes.")
                print(status)
                exit(1)
            shell.call(['git', 'checkout', branch], echo=True)

            # If we were asked to reset to the specified branch, do the hard
            # reset and return.
            if reset_to_remote and not cross_repo:
                shell.call(['git', 'reset', '--hard', "origin/%s" % branch],
                           echo=True)
                return

        # Prior to Git 2.6, this is the way to do a "git pull
        # --rebase" that respects rebase.autostash.  See
        # http://stackoverflow.com/a/30209750/125349
        if not cross_repo:
            shell.call(["git", "rebase", "FETCH_HEAD"], echo=True)
        shell.call(["git", "submodule", "update", "--recursive"],
                   echo=True)


def update_repository_to_tag(args, repo_name, repo_path, tag_name):
    with shell.pushd(repo_path, dry_run=False, echo=False):
        tag_exists = shell.capture(['git', 'ls-remote', '--tags',
                                    'origin', tag_name], echo=False)
        if not tag_exists:
            print("--- Skipping '" + repo_name + "' ---")
            return
        update_single_repository(repo_path,
                                 tag_name,
                                 args.reset_to_remote,
                                 args.clean,
                                 cross_repo=True)


def update_repository_to_scheme(
        args, config, repo_name, repo_path, scheme_name, cross_repos_pr):
    cross_repo = False
    repo_branch = scheme_name
    # This loop is only correct, since we know that each alias set has
    # unique contents. This is checked by verify config. Thus the first
    # branch scheme data that has scheme_name as one of its aliases is
    # the only possible correct answer.
    for v in config['branch-schemes'].values():
        if scheme_name not in v['aliases']:
            continue
        repo_branch = v['repos'][repo_name]
        remote_repo_id = config['repos'][repo_name]['remote']['id']
        if remote_repo_id in cross_repos_pr:
            cross_repo = True
            pr_id = cross_repos_pr[remote_repo_id]
            repo_branch = "ci_pr_{0}".format(pr_id)
            with shell.pushd(repo_path, dry_run=False, echo=False):
                shell.call(["git", "checkout", v['repos'][repo_name]],
                           echo=True)
                shell.capture(["git", "branch", "-D", repo_branch],
                              echo=True, allow_non_zero_exit=True)
                shell.call(["git", "fetch", "origin",
                            "pull/{0}/merge:{1}"
                            .format(pr_id, repo_branch)], echo=True)
        break
    update_single_repository(repo_path,
                             repo_branch,
                             args.reset_to_remote,
                             args.clean,
                             cross_repo)


def update_all_repositories(args, config, scheme_name, cross_repos_pr):
    for repo_name in config['repos'].keys():
        if repo_name in args.skip_repository_list:
            print("--- Skipping '" + repo_name + "' ---")
            continue
        repo_path = os.path.join(SWIFT_SOURCE_ROOT, repo_name)
        if args.tag:
            update_repository_to_tag(args, repo_name, repo_path, args.tag)
        elif scheme_name:
            update_repository_to_scheme(args,
                                        config,
                                        repo_name,
                                        repo_path,
                                        scheme_name,
                                        cross_repos_pr)
        else:
            update_single_repository(repo_path,
                                     branch=None,
                                     reset_to_remote=args.reset_to_remote,
                                     should_clean=args.clean,
                                     cross_repo=False)


def obtain_additional_swift_sources(
        config, with_ssh, scheme_name, skip_history, skip_repository_list):
    with shell.pushd(SWIFT_SOURCE_ROOT, dry_run=False,
                     echo=False):
        for repo_name, repo_info in config['repos'].items():
            if repo_name in skip_repository_list:
                print("--- Skipping '" + repo_name + "' ---")
                continue

            if os.path.isdir(os.path.join(repo_name, ".git")):
                continue

            print("--- Cloning '" + repo_name + "' ---")

            # If we have a url override, use that url instead of
            # interpolating.
            remote_repo_info = repo_info['remote']
            if 'url' in remote_repo_info:
                remote = remote_repo_info['url']
            else:
                remote_repo_id = remote_repo_info['id']
                if with_ssh is True or 'https-clone-pattern' not in config:
                    remote = config['ssh-clone-pattern'] % remote_repo_id
                else:
                    remote = config['https-clone-pattern'] % remote_repo_id

            if skip_history:
                shell.call(['git', 'clone', '--recursive', '--depth', '1',
                            remote, repo_name], echo=True)
            else:
                shell.call(['git', 'clone', '--recursive', remote,
                            repo_name], echo=True)
            if scheme_name:
                for v in config['branch-schemes'].values():
                    if scheme_name not in v['aliases']:
                        continue
                    repo_branch = v['repos'][repo_name]
                    break
                else:
                    repo_branch = scheme_name
                src_path = os.path.join(SWIFT_SOURCE_ROOT, repo_name,
                                        ".git")
                shell.call(['git', '--git-dir', src_path, '--work-tree',
                            os.path.join(SWIFT_SOURCE_ROOT, repo_name),
                            'checkout', repo_branch], echo=False)
    with shell.pushd(os.path.join(SWIFT_SOURCE_ROOT, repo_name),
                     dry_run=False, echo=False):
        shell.call(["git", "submodule", "update", "--recursive"],
                   echo=False)


def dump_repo_hashes(config):
    max_len = reduce(lambda acc, x: max(acc, len(x)),
                     config['repos'].keys(), 0)
    fmt = "{:<%r}{}" % (max_len+5)
    for repo_name, repo_info in sorted(config['repos'].items(),
                                       key=lambda x: x[0]):
        with shell.pushd(os.path.join(SWIFT_SOURCE_ROOT, repo_name),
                         dry_run=False,
                         echo=False):
            h = shell.capture(["git", "log", "--oneline", "-n", "1"],
                              echo=False).strip()
            print(fmt.format(repo_name, h))


def validate_config(config):
    # Make sure that our branch-names are unique.
    scheme_names = config['branch-schemes'].keys()
    if len(scheme_names) != len(set(scheme_names)):
        raise RuntimeError('Configuration file has duplicate schemes?!')

    # Then make sure the alias names used by our branches are unique.
    #
    # We do this by constructing a list consisting of len(names),
    # set(names). Then we reduce over that list summing the counts and taking
    # the union of the sets. We have uniqueness if the length of the union
    # equals the length of the sum of the counts.
    data = [(len(v['aliases']), set(v['aliases']))
            for v in config['branch-schemes'].values()]
    result = reduce(lambda acc, x: (acc[0] + x[0], acc[1] | x[1]), data,
                    (0, set([])))
    if result[0] == len(result[1]):
        return
    raise RuntimeError('Configuration file has schemes with duplicate '
                       'aliases?!')


def main():
    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description="""
repositories.

By default, updates your checkouts of Swift, SourceKit, LLDB, and SwiftPM.""")
    parser.add_argument(
        "--clone",
        help="Obtain Sources for Swift and Related Projects",
        action="store_true")
    parser.add_argument(
        "--clone-with-ssh",
        help="Obtain Sources for Swift and Related Projects via SSH",
        action="store_true")
    parser.add_argument(
        "--skip-history",
        help="Skip histories when obtaining sources",
        action="store_true")
    parser.add_argument(
        "--skip-repository",
        metavar="DIRECTORY",
        default=[],
        help="Skip the specified repository",
        dest='skip_repository_list',
        action="append")
    parser.add_argument(
        "--scheme", "--branch",
        help='Use branches from the specified branch-scheme',
        metavar='BRANCH-SCHEME',
        dest='scheme')
    parser.add_argument(
        '--reset-to-remote',
        help='Reset each branch to the remote state.',
        action='store_true')
    parser.add_argument(
        '--clean',
        help='Clean unrelated files from each repository.',
        action='store_true')
    parser.add_argument(
        "--config",
        default=os.path.join(SCRIPT_DIR, "update-checkout-config.json"),
        help="Configuration file to use")
    parser.add_argument(
        "--github-comment",
        help="""Check out related pull requests referenced in the given
        free-form GitHub-style comment.""",
        metavar='GITHUB-COMMENT',
        dest='github_comment')
    parser.add_argument(
        '--dump-hashes',
        action='store_true',
        help='Dump the git hashes of all repositories being tracked')
    parser.add_argument(
        "--tag",
        help="""Check out each repository to the specified tag.""",
        metavar='TAG-NAME')
    args = parser.parse_args()

    clone = args.clone
    clone_with_ssh = args.clone_with_ssh
    skip_history = args.skip_history
    scheme = args.scheme
    github_comment = args.github_comment

    with open(args.config) as f:
        config = json.load(f)
    validate_config(config)

    if args.dump_hashes:
        dump_repo_hashes(config)
        return 0

    cross_repos_pr = {}
    if github_comment:
        regex_pr = r'(apple/[-a-zA-Z0-9_]+/pull/\d+|apple/[-a-zA-Z0-9_]+#\d+)'
        repos_with_pr = re.findall(regex_pr, github_comment)
        print("Found related pull requests:", str(repos_with_pr))
        repos_with_pr = [pr.replace('/pull/', '#') for pr in repos_with_pr]
        cross_repos_pr = dict(pr.split('#') for pr in repos_with_pr)

    if clone or clone_with_ssh:
        # If branch is None, default to using the default branch alias
        # specified by our configuration file.
        if scheme is None:
            scheme = config['default-branch-scheme']

        obtain_additional_swift_sources(
            config, clone_with_ssh, scheme, skip_history,
            args.skip_repository_list)

    update_all_repositories(args, config, scheme, cross_repos_pr)

    return 0

if __name__ == "__main__":
    sys.exit(main())
