#!/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 Optional, 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_git_hook(hook: str,
                     command: Sequence[Union[Path, str]],
                     repository: Union[Path, str] = '.') -> None:
    """Installs a simple Git hook that executes the provided command.

    Args:
      hook: Git hook to install, e.g. 'pre-push'.
      command: Command to execute as the hook. The command is executed from the
          root of the repo. Arguments are sanitised with `shlex.quote`, except
          for any arguments are equal to f'${stdin_arg}' for some `stdin_arg`
          that matches a standard-input argument to the git hook.
      repository: Repository to install the hook in.
    """
    if not command:
        raise ValueError('The command cannot be empty!')

    root = git_repo_root(repository).resolve()

    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]
    args = (_replace_arg_in_hook(str(a), unquoted_args) for a in command[1:])

    command_str = ' '.join([shlex.quote(str(command[0])), *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(command_str)

    hook_path.chmod(0o755)
    logging.info('Installed %s hook for `%s` at %s', hook, command_str,
                 hook_path)


def argument_parser(
    parser: Optional[argparse.ArgumentParser] = 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('command',
                        nargs='*',
                        help='Command to run in the commit hook')

    return parser


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