#!/usr/bin/env python3
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

import argparse
import fnmatch
import logging as log
import os
import re
import shutil
import subprocess
import sys
import tempfile
import textwrap
from pathlib import Path

import hjson

DESC = """vendor, copy source code from upstream into this repository"""

EXCLUDE_ALWAYS = ['.git']

LOCK_FILE_HEADER = """// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

// This file is generated by the util/vendor script. Please do not modify it
// manually.

"""

verbose = False


def git_is_clean_workdir(git_workdir):
    """Check if the git working directory is clean (no unstaged or staged changes)"""
    cmd = ['git', 'status', '--untracked-files=no', '--porcelain']
    modified_files = subprocess.run(cmd,
                                    cwd=git_workdir,
                                    check=True,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE).stdout.strip()
    return not modified_files


def path_resolve(path, base_dir=Path.cwd()):
    """Create an absolute path. Relative paths are resolved using base_dir as base."""

    if isinstance(path, str):
        path = Path(path)

    if path.is_absolute():
        return path

    return (base_dir / path).resolve()


def github_qualify_references(log, repo_userorg, repo_name):
    """ Replace "unqualified" GitHub references with "fully qualified" one

    GitHub automatically links issues and pull requests if they have a specific
    format. Links can be qualified with the user/org name and the repository
    name, or unqualified, if they only contain the issue or pull request number.

    This function converts all unqualified references to qualified ones.

    See https://help.github.com/en/articles/autolinked-references-and-urls#issues-and-pull-requests
    for a documentation of all supported formats.
    """

    r = re.compile(r"(^|[^\w])(?:#|[gG][hH]-)(\d+)\b")
    repl_str = r'\1%s/%s#\2' % (repo_userorg, repo_name)
    return [r.sub(repl_str, l) for l in log]


def test_github_qualify_references():
    repo_userorg = 'lowRISC'
    repo_name = 'ibex'

    # Unqualified references, should be replaced
    items_unqualified = [
        '#28',
        'GH-27',
        'klaus #27',
        'Fixes #27',
        'Fixes #27 and #28',
        '(#27)',
        'something (#27) done',
        '#27 and (GH-38)',
    ]
    exp_items_unqualified = [
        'lowRISC/ibex#28',
        'lowRISC/ibex#27',
        'klaus lowRISC/ibex#27',
        'Fixes lowRISC/ibex#27',
        'Fixes lowRISC/ibex#27 and lowRISC/ibex#28',
        '(lowRISC/ibex#27)',
        'something (lowRISC/ibex#27) done',
        'lowRISC/ibex#27 and (lowRISC/ibex#38)',
    ]
    assert github_qualify_references(items_unqualified, repo_userorg,
                                     repo_name) == exp_items_unqualified

    # Qualified references, should stay as they are
    items_qualified = [
        'Fixes lowrisc/ibex#27',
        'lowrisc/ibex#2',
    ]
    assert github_qualify_references(items_qualified, repo_userorg,
                                     repo_name) == items_qualified

    # Invalid references, should stay as they are
    items_invalid = [
        'something#27',
        'lowrisc/ibex#',
    ]
    assert github_qualify_references(items_invalid, repo_userorg,
                                     repo_name) == items_invalid


def test_github_parse_url():
    assert github_parse_url('https://example.com/something/asdf.git') is None
    assert github_parse_url('https://github.com/lowRISC/ibex.git') == (
        'lowRISC', 'ibex')
    assert github_parse_url('https://github.com/lowRISC/ibex') == ('lowRISC',
                                                                   'ibex')
    assert github_parse_url('git@github.com:lowRISC/ibex.git') == ('lowRISC',
                                                                   'ibex')


def github_parse_url(github_repo_url):
    """Parse a GitHub repository URL into its parts.

    Return a tuple (userorg, name), or None if the parsing failed.
    """

    regex = r"(?:@github\.com\:|\/github\.com\/)([a-zA-Z\d-]+)\/([a-zA-Z\d-]+)(?:\.git)?$"
    m = re.search(regex, github_repo_url)
    if m is None:
        return None
    return (m.group(1), m.group(2))


def produce_shortlog(clone_dir, old_rev, new_rev):
    """ Produce a list of changes between two revisions, one revision per line

    Merges are excluded"""
    cmd = [
        'git', '-C',
        str(clone_dir), 'log', '--pretty=format:%s (%aN)', '--no-merges',
        old_rev + '..' + new_rev, '.'
    ]
    try:
        proc = subprocess.run(cmd,
                              cwd=clone_dir,
                              check=True,
                              stdout=subprocess.PIPE,
                              stderr=subprocess.PIPE,
                              universal_newlines=True)
        return proc.stdout.splitlines()
    except subprocess.CalledProcessError as e:
        log.error("Unable to capture shortlog: %s", e.stderr)
        return ""


def format_list_to_str(list, width=70):
    """ Create Markdown-style formatted string from a list of strings """
    wrapper = textwrap.TextWrapper(initial_indent="* ",
                                   subsequent_indent="  ",
                                   width=width)
    return '\n'.join([wrapper.fill(s) for s in list])


def refresh_patches(desc):
    if not 'patch_repo' in desc:
        log.fatal('Unable to refresh patches, patch_repo not set in config.')
        sys.exit(1)

    patch_dir_abs = path_resolve(desc['patch_dir'], desc['_base_dir'])
    log.info('Refreshing patches in %s' % (str(patch_dir_abs), ))

    # remove existing patches
    for patch in patch_dir_abs.glob('*.patch'):
        os.unlink(str(patch))

    # get current patches
    _export_patches(desc['patch_repo']['url'], patch_dir_abs,
                    desc['patch_repo']['rev_base'],
                    desc['patch_repo']['rev_patched'])


def _export_patches(patchrepo_clone_url, target_patch_dir, upstream_rev,
                    patched_rev):
    clone_dir = Path(tempfile.mkdtemp())
    try:
        clone_git_repo(patchrepo_clone_url, clone_dir, patched_rev)
        rev_range = 'origin/' + upstream_rev + '..' + 'origin/' + patched_rev
        cmd = ['git', 'format-patch', '-o', str(target_patch_dir), rev_range]
        if not verbose:
            cmd += ['-q']
        subprocess.run(cmd, cwd=clone_dir, check=True)

    finally:
        shutil.rmtree(str(clone_dir), ignore_errors=True)


def import_from_upstream(upstream_path, target_path, exclude_files=[]):
    log.info('Copying upstream sources to %s', target_path)
    # remove existing directories before importing them again
    shutil.rmtree(str(target_path), ignore_errors=True)

    # import new contents for rtl directory
    _cp_from_upstream(upstream_path, target_path, exclude_files)


def apply_patch(basedir, patchfile, strip_level=1):
    cmd = ['git', 'apply', '-p' + str(strip_level), patchfile]
    if verbose:
        cmd += ['--verbose']
    subprocess.run(cmd, cwd=basedir, check=True)


def clone_git_repo(repo_url, clone_dir, rev='master'):
    log.info('Cloning upstream repository %s @ %s', repo_url, rev)

    cmd = [
        'git', 'clone', '--no-single-branch', '-b', rev, repo_url, clone_dir
    ]
    if not verbose:
        cmd += ['-q']
    subprocess.run(cmd, check=True)

    # Get revision information
    cmd = ['git', '-C', str(clone_dir), 'rev-parse', 'HEAD']
    rev = subprocess.run(cmd,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE,
                         check=True,
                         universal_newlines=True).stdout.strip()
    log.info('Cloned at revision %s', rev)
    return rev


def git_get_short_rev(clone_dir, rev):
    """ Get the shortened SHA-1 hash for a revision """
    cmd = ['git', '-C', str(clone_dir), 'rev-parse', '--short', rev]
    short_rev = subprocess.run(cmd,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE,
                               check=True,
                               universal_newlines=True).stdout.strip()
    return short_rev


def git_add_commit(repo_base, paths, commit_msg):
    """ Stage and commit all changes in paths"""

    # Stage all changes
    for p in paths:
        cmd_add = ['git', '-C', str(repo_base), 'add', str(p)]
        subprocess.run(cmd_add, check=True)

    cmd_commit = ['git', '-C', str(repo_base), 'commit', '-s', '-F', '-']
    try:
        subprocess.run(cmd_commit,
                       check=True,
                       universal_newlines=True,
                       input=commit_msg)
    except subprocess.CalledProcessError as e:
        log.warning("Unable to create commit. Are there no changes?")


def ignore_patterns(base_dir, *patterns):
    """Similar to shutil.ignore_patterns, but with support for directory excludes."""
    def _rel_to_base(path, name):
        return os.path.relpath(os.path.join(path, name), base_dir)

    def _ignore_patterns(path, names):
        ignored_names = []
        for pattern in patterns:
            pattern_matches = [
                n for n in names
                if fnmatch.fnmatch(_rel_to_base(path, n), pattern)
            ]
            ignored_names.extend(pattern_matches)
        return set(ignored_names)

    return _ignore_patterns


def _cp_from_upstream(src, dest, exclude=[]):
    shutil.copytree(str(src),
                    str(dest),
                    ignore=ignore_patterns(str(src), *exclude))


def main(argv):
    parser = argparse.ArgumentParser(prog="vendor", description=DESC)
    parser.add_argument('--refresh-patches',
                        action='store_true',
                        help='Refresh the patches from the patch repository')
    parser.add_argument('--commit',
                        '-c',
                        action='store_true',
                        help='Commit the changes')
    parser.add_argument('desc_file',
                        metavar='file',
                        type=argparse.FileType('r', encoding='UTF-8'),
                        help='vendoring description file (*.vendor.hjson)')
    parser.add_argument('--verbose', '-v', action='store_true', help='Verbose')
    args = parser.parse_args()

    global verbose
    verbose = args.verbose
    if (verbose):
        log.basicConfig(format="%(levelname)s: %(message)s", level=log.DEBUG)
    else:
        log.basicConfig(format="%(levelname)s: %(message)s")

    desc_file_path = Path(args.desc_file.name).resolve()
    vendor_file_base_dir = desc_file_path.parent

    # Precondition: Ensure description file matches our naming rules
    if not str(desc_file_path).endswith('.vendor.hjson'):
        log.fatal("Description file names must have a .vendor.hjson suffix.")
        raise SystemExit(1)

    # Precondition: Check for a clean working directory when commit is requested
    if args.commit:
        if not git_is_clean_workdir(vendor_file_base_dir):
            log.fatal("A clean git working directory is required for "
                      "--commit/-c. git stash your changes and try again.")
            raise SystemExit(1)

    # Load description file
    try:
        desc = hjson.loads(args.desc_file.read(), use_decimal=True)
    except ValueError:
        raise SystemExit(sys.exc_info()[1])
    desc['_base_dir'] = vendor_file_base_dir

    # Load lock file contents (if possible)
    desc_file_path_str = str(desc_file_path)
    lock_file_path = Path(
        desc_file_path_str[:desc_file_path_str.find('.vendor.hjson')] +
        '.lock.hjson')
    try:
        with open(lock_file_path, 'r') as f:
            lock = hjson.loads(f.read(), use_decimal=True)
    except FileNotFoundError:
        log.warning(
            "Unable to read lock file %s. Assuming this is the first import.",
            lock_file_path)
        lock = None

    if args.refresh_patches:
        refresh_patches(desc)

    clone_dir = Path(tempfile.mkdtemp())
    try:
        # clone upstream repository
        upstream_new_rev = clone_git_repo(desc['upstream']['url'], clone_dir,
                                          desc['upstream']['rev'])

        upstream_only_subdir = ''
        clone_subdir = clone_dir
        if 'only_subdir' in desc['upstream']:
            upstream_only_subdir = desc['upstream']['only_subdir']
            clone_subdir = clone_dir / upstream_only_subdir
            if not clone_subdir.is_dir():
                log.fatal("subdir '%s' does not exist in repo", upstream_only_subdir)
                raise SystemExit(1)


        # apply patches to upstream sources
        if 'patch_dir' in desc:
            patches = path_resolve(desc['patch_dir'],
                                   vendor_file_base_dir).glob('*.patch')
            for patch in sorted(patches):
                log.info("Applying patch %s" % str(patch))
                apply_patch(clone_subdir, str(patch))

        # import selected (patched) files from upstream repo
        exclude_files = []
        if 'exclude_from_upstream' in desc:
            exclude_files += desc['exclude_from_upstream']
        exclude_files += EXCLUDE_ALWAYS

        import_from_upstream(
            clone_subdir, path_resolve(desc['target_dir'], vendor_file_base_dir),
            exclude_files)

        # get shortlog
        get_shortlog = True
        if not lock:
            get_shortlog = False
            log.warning(
                "No lock file exists. Unable to get the log of changes.")
        elif lock['upstream']['url'] != desc['upstream']['url']:
            get_shortlog = False
            log.warning(
                "The repository URL changed since the last run. Unable to get log of changes."
            )
        elif upstream_new_rev == lock['upstream']['rev']:
            get_shortlog = False
            log.warning("Re-importing upstream revision %s", upstream_new_rev)

        shortlog = None
        if get_shortlog:
            shortlog = produce_shortlog(clone_subdir, lock['upstream']['rev'],
                                        upstream_new_rev)

            # Ensure fully-qualified issue/PR references for GitHub repos
            gh_repo_info = github_parse_url(desc['upstream']['url'])
            if gh_repo_info:
                shortlog = github_qualify_references(shortlog, gh_repo_info[0],
                                                     gh_repo_info[1])

            log.info("Changes since the last import:\n" +
                     format_list_to_str(shortlog))

        # write lock file
        lock = {}
        lock['upstream'] = desc['upstream']
        lock['upstream']['rev'] = upstream_new_rev
        with open(lock_file_path, 'w', encoding='UTF-8') as f:
            f.write(LOCK_FILE_HEADER)
            hjson.dump(lock, f)
            f.write("\n")
            log.info("Wrote lock file %s", lock_file_path)

        # Commit changes
        if args.commit:
            sha_short = git_get_short_rev(clone_subdir, upstream_new_rev)

            repo_info = github_parse_url(desc['upstream']['url'])
            if repo_info is not None:
                sha_short = "%s/%s@%s" % (repo_info[0], repo_info[1],
                                          sha_short)

            commit_msg_subject = 'Update %s to %s' % (desc['name'], sha_short)
            subdir_msg = ' '
            if upstream_only_subdir:
                subdir_msg = ' subdir %s in ' % upstream_only_subdir
            intro = 'Update code from%supstream repository %s to revision %s' % (
                subdir_msg, desc['upstream']['url'], upstream_new_rev)
            commit_msg_body = textwrap.fill(intro, width=70)

            if shortlog:
                commit_msg_body += "\n\n"
                commit_msg_body += format_list_to_str(shortlog, width=70)

            commit_msg = commit_msg_subject + "\n\n" + commit_msg_body

            commit_paths = []
            commit_paths.append(
                path_resolve(desc['target_dir'], vendor_file_base_dir))
            if args.refresh_patches:
                commit_paths.append(
                    path_resolve(desc['patch_dir'], vendor_file_base_dir))
            commit_paths.append(lock_file_path)

            git_add_commit(vendor_file_base_dir, commit_paths, commit_msg)

    finally:
        shutil.rmtree(str(clone_dir), ignore_errors=True)

    log.info('Import finished')


if __name__ == '__main__':
    try:
        main(sys.argv)
    except subprocess.CalledProcessError as e:
        log.fatal("Called program '%s' returned with %d.\n"
                  "STDOUT:\n%s\n"
                  "STDERR:\n%s\n" %
                  (" ".join(e.cmd), e.returncode, e.stdout, e.stderr))
        raise
