#!/usr/bin/env python3
# Copyright 2020 The Pigweed Authors
#
# 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
#
#     https://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.
"""Creates a Git hook that calls a script with certain arguments."""

import argparse
import logging
import os
from pathlib import Path
import re
import shlex
import subprocess
from typing import Sequence, Union

_LOG: logging.Logger = logging.getLogger(__name__)


def git_repo_root(path: Union[Path, str]) -> Path:
    return Path(
        subprocess.run(['git', '-C', path, 'rev-parse', '--show-toplevel'],
                       check=True,
                       stdout=subprocess.PIPE).stdout.strip().decode())


def _stdin_args_for_hook(hook) -> Sequence[str]:
    """Gives stdin arguments for each hook.

    See https://git-scm.com/docs/githooks for more information.
    """
    if hook == 'pre-push':
        return ('local_ref', 'local_object_name', 'remote_ref',
                'remote_object_name')
    if hook in ('pre-receive', 'post-receive', 'reference-transaction'):
        return ('old_value', 'new_value', 'ref_name')
    if hook == 'post-rewrite':
        return ('old_object_name', 'new_object_name')
    return ()


def _replace_arg_in_hook(arg: str, unquoted_args: Sequence[str]) -> str:
    if arg in unquoted_args:
        return arg
    return shlex.quote(arg)


def install_hook(script,
                 hook: str,
                 args: Sequence[str] = (),
                 repository: Union[Path, str] = '.') -> None:
    """Installs a simple Git hook that calls a script with arguments.

    Args:
      script: Path to the script to run in the hook.
      hook: Git hook to install, e.g. 'pre-push'.
      args: Arguments to pass to `script` when it is run in the hook. These will
        be sanitised with `shlex.quote`, except for any arguments are equal to
        f'${stdin_arg}' for some `stdin_arg` which matches a standard-input
        argument to the git hook.
      repository: Repository to install the hook in.
    """
    root = git_repo_root(repository).resolve()
    script = os.path.relpath(script, root)

    if root.joinpath('.git').is_dir():
        hook_path = root.joinpath('.git', 'hooks', hook)
    else:  # This repo is probably a submodule with a .git file instead
        match = re.match('^gitdir: (.*)$', root.joinpath('.git').read_text())
        if not match:
            raise ValueError('Unexpected format for .git file')

        hook_path = root.joinpath(match.group(1), 'hooks', hook).resolve()

    hook_path.parent.mkdir(exist_ok=True)

    hook_stdin_args = _stdin_args_for_hook(hook)
    read_stdin_command = 'read ' + ' '.join(hook_stdin_args)

    unquoted_args = [f'${arg}' for arg in hook_stdin_args]
    script_command = ' '.join(
        _replace_arg_in_hook(arg, unquoted_args) for arg in (script, *args))

    with hook_path.open('w') as file:
        line = lambda *args: print(*args, file=file)

        line('#!/bin/sh')
        line(f'# {hook} hook generated by {__file__}')
        line()
        line('# Unset Git environment variables, which are set when this is ')
        line('# run as a Git hook. These environment variables cause issues ')
        line('# when trying to run Git commands on other repos from a ')
        line('# submodule hook.')
        line('unset $(git rev-parse --local-env-vars)')
        line()
        line('# Read the stdin args for the hook, made available by git.')
        line(read_stdin_command)
        line()
        line(script_command)

    hook_path.chmod(0o755)
    logging.info('Created %s hook for %s at %s', hook, script, hook_path)


def argument_parser(parser=None) -> argparse.ArgumentParser:
    if parser is None:
        parser = argparse.ArgumentParser(description=__doc__)

    def path(arg: str) -> Path:
        if not os.path.exists(arg):
            raise argparse.ArgumentTypeError(f'"{arg}" is not a valid path')

        return Path(arg)

    parser.add_argument(
        '-r',
        '--repository',
        default='.',
        type=path,
        help='Path to the repository in which to install the hook')
    parser.add_argument('--hook',
                        required=True,
                        help='Which type of Git hook to create')
    parser.add_argument('-s',
                        '--script',
                        required=True,
                        type=path,
                        help='Path to the script to execute in the hook')
    parser.add_argument('args',
                        nargs='*',
                        help='Arguments to provide to the commit hook')

    return parser


if __name__ == '__main__':
    logging.basicConfig(format='%(message)s', level=logging.INFO)
    install_hook(**vars(argument_parser().parse_args()))
