#!/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 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 install_hook(script,
                 hook: str,
                 args: Sequence[str] = (),
                 repository: Union[Path, str] = '.') -> None:
    """Installs a simple Git hook that calls a script with arguments."""
    root = git_repo_root(repository).resolve()
    script = os.path.relpath(script, root)

    hook_path = root.joinpath('.git', 'hooks', hook)

    command = ' '.join(shlex.quote(arg) 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(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()))
