from __future__ import annotations

import argparse
import shlex
import subprocess
from typing import Sequence

from pre_commit_hooks.util import cmd_output
from pre_commit_hooks.util import zsplit

ORDINARY_CHANGED_ENTRIES_MARKER = '1'
PERMS_LINK = '120000'
PERMS_NONEXIST = '000000'


def find_destroyed_symlinks(files: Sequence[str]) -> list[str]:
    destroyed_links: list[str] = []
    if not files:
        return destroyed_links
    for line in zsplit(
        cmd_output('git', 'status', '--porcelain=v2', '-z', '--', *files),
    ):
        splitted = line.split(' ')
        if splitted and splitted[0] == ORDINARY_CHANGED_ENTRIES_MARKER:
            # https://git-scm.com/docs/git-status#_changed_tracked_entries
            (
                _, _, _,
                mode_HEAD,
                mode_index,
                _,
                hash_HEAD,
                hash_index,
                *path_splitted,
            ) = splitted
            path = ' '.join(path_splitted)
            if (
                    mode_HEAD == PERMS_LINK and
                    mode_index != PERMS_LINK and
                    mode_index != PERMS_NONEXIST
            ):
                if hash_HEAD == hash_index:
                    # if old and new hashes are equal, it's not needed to check
                    # anything more, we've found a destroyed symlink for sure
                    destroyed_links.append(path)
                else:
                    # if old and new hashes are *not* equal, it doesn't mean
                    # that everything is OK - new file may be altered
                    # by something like trailing-whitespace and/or
                    # mixed-line-ending hooks so we need to go deeper
                    SIZE_CMD = ('git', 'cat-file', '-s')
                    size_index = int(cmd_output(*SIZE_CMD, hash_index).strip())
                    size_HEAD = int(cmd_output(*SIZE_CMD, hash_HEAD).strip())

                    # in the worst case new file may have CRLF added
                    # so check content only if new file is bigger
                    # not more than 2 bytes compared to the old one
                    if size_index <= size_HEAD + 2:
                        head_content = subprocess.check_output(
                            ('git', 'cat-file', '-p', hash_HEAD),
                        ).rstrip()
                        index_content = subprocess.check_output(
                            ('git', 'cat-file', '-p', hash_index),
                        ).rstrip()
                        if head_content == index_content:
                            destroyed_links.append(path)
    return destroyed_links


def main(argv: Sequence[str] | None = None) -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument('filenames', nargs='*', help='Filenames to check.')
    args = parser.parse_args(argv)
    destroyed_links = find_destroyed_symlinks(files=args.filenames)
    if destroyed_links:
        print('Destroyed symlinks:')
        for destroyed_link in destroyed_links:
            print(f'- {destroyed_link}')
        print('You should unstage affected files:')
        print(
            '\tgit reset HEAD -- {}'.format(
                ' '.join(shlex.quote(link) for link in destroyed_links),
            ),
        )
        print(
            'And retry commit. As a long term solution '
            'you may try to explicitly tell git that your '
            'environment does not support symlinks:',
        )
        print('\tgit config core.symlinks false')
        return 1
    else:
        return 0


if __name__ == '__main__':
    raise SystemExit(main())
