#!/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:
    """This function is deprecated; use install_git_hook instead.

    This version of the function takes the script separately from the arguments
    and calculates the relative path to the script from the root of the repo.
    This does not work well when the path is to a file installed in the virtual
    environment, since the execute permission may be lost. Instead of using a
    path to a script, invoke the script from `python -m` or the `pw` command.
    """
    root = git_repo_root(repository).resolve()
    install_git_hook(hook, [os.path.relpath(script, root), *args], repository)


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=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()))
