#!/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_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: 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()))
