# Copyright (C) 2018 The Android Open Source Project
#
# 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
#
#      http://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.
"""Helper functions to communicate with Git."""

import datetime
import re
import subprocess
from pathlib import Path

import fileutils
import hashtags
import reviewers
from manifest import Manifest

UNWANTED_TAGS = ["*alpha*", "*Alpha*", "*beta*", "*Beta*", "*rc*", "*RC*", "*test*"]


def fetch(proj_path: Path, remote_name: str, branch: str | None = None) -> None:
    """Runs git fetch.

    Args:
        proj_path: Path to Git repository.
        remote_name: A string to specify remote names.
    """
    cmd = ['git', 'fetch', '--tags', remote_name] + ([branch] if branch is not None else [])
    subprocess.run(cmd, capture_output=True, cwd=proj_path, check=True)


def add_remote(proj_path: Path, name: str, url: str) -> None:
    """Adds a git remote.

    Args:
        proj_path: Path to Git repository.
        name: Name of the new remote.
        url: Url of the new remote.
    """
    cmd = ['git', 'remote', 'add', name, url]
    subprocess.run(cmd, cwd=proj_path, check=True)


def remove_remote(proj_path: Path, name: str) -> None:
    """Removes a git remote."""
    cmd = ['git', 'remote', 'remove', name]
    subprocess.run(cmd, cwd=proj_path, check=True)


def list_remotes(proj_path: Path) -> dict[str, str]:
    """Lists all Git remotes.

    Args:
        proj_path: Path to Git repository.

    Returns:
        A dict from remote name to remote url.
    """
    def parse_remote(line: str) -> tuple[str, str]:
        split = line.split()
        return split[0], split[1]

    cmd = ['git', 'remote', '-v']
    out = subprocess.run(cmd, capture_output=True, cwd=proj_path, check=True,
                         text=True).stdout
    lines = out.splitlines()
    return dict([parse_remote(line) for line in lines])


def detect_default_branch(proj_path: Path, remote_name: str) -> str:
    """Gets the name of the upstream's default branch to use."""
    cmd = ['git', 'remote', 'show', remote_name]
    out = subprocess.run(cmd, capture_output=True, cwd=proj_path, check=True,
                         text=True).stdout
    lines = out.splitlines()
    for line in lines:
        if "HEAD branch" in line:
            return line.split()[-1]
    raise RuntimeError(
        f"Could not find HEAD branch in 'git remote show {remote_name}'"
    )


def get_sha_for_branch(proj_path: Path, branch: str):
    """Gets the hash SHA for a branch."""
    cmd = ['git', 'rev-parse', branch]
    return subprocess.run(cmd, capture_output=True, cwd=proj_path, check=True,
                          text=True).stdout.strip()


def get_most_recent_tag(proj_path: Path, branch: str) -> str | None:
    """Finds the most recent tag that is reachable from HEAD."""
    cmd = ['git', 'describe', '--tags', branch, '--abbrev=0'] + \
          [f'--exclude={unwanted_tag}' for unwanted_tag in UNWANTED_TAGS]
    try:
        out = subprocess.run(cmd, capture_output=True, cwd=proj_path, check=True,
                            text=True).stdout.strip()
        return out
    except subprocess.CalledProcessError as ex:
        if "fatal: No names found" in ex.stderr:
            return None
        if "fatal: No tags can describe" in ex.stderr:
            return None
        raise


# pylint: disable=redefined-outer-name
def get_commit_time(proj_path: Path, commit: str) -> datetime.datetime:
    """Gets commit time of one commit."""
    cmd = ['git', 'show', '-s', '--format=%ct', commit]
    out = subprocess.run(cmd, capture_output=True, cwd=proj_path, check=True,
                         text=True).stdout
    return datetime.datetime.fromtimestamp(int(out.strip()))


def list_remote_branches(proj_path: Path, remote_name: str) -> list[str]:
    """Lists all branches for a remote."""
    cmd = ['git', 'branch', '-r']
    lines = subprocess.run(cmd, capture_output=True, cwd=proj_path, check=True,
                           text=True).stdout.splitlines()
    stripped = [line.strip() for line in lines]
    remote_path = remote_name + '/'
    return [
        line[len(remote_path):] for line in stripped
        if line.startswith(remote_path)
    ]


def list_local_branches(proj_path: Path) -> list[str]:
    """Lists all local branches."""
    cmd = ['git', 'branch', '--format=%(refname:short)']
    lines = subprocess.run(cmd, capture_output=True, cwd=proj_path, check=True,
                           text=True).stdout.splitlines()
    return lines


COMMIT_PATTERN = r'^[a-f0-9]{40}$'
COMMIT_RE = re.compile(COMMIT_PATTERN)


# pylint: disable=redefined-outer-name
def is_commit(commit: str) -> bool:
    """Whether a string looks like a SHA1 hash."""
    return bool(COMMIT_RE.match(commit))


def merge(proj_path: Path, branch: str) -> None:
    """Merges a branch."""
    try:
        cmd = ['git', 'merge', branch, '--no-commit']
        subprocess.run(cmd, cwd=proj_path, check=True)
    except subprocess.CalledProcessError as err:
        if hasattr(err, "output"):
            print(err.output)
        if not merge_conflict(proj_path):
            raise


def merge_conflict(proj_path: Path) -> bool:
    """Checks if there was a merge conflict."""
    cmd = ['git', 'ls-files', '--unmerged']
    out = subprocess.run(cmd, capture_output=True, cwd=proj_path, check=True,
                         text=True).stdout
    return bool(out)


def add_file(proj_path: Path, file_name: str) -> None:
    """Stages a file."""
    cmd = ['git', 'add', file_name]
    subprocess.run(cmd, cwd=proj_path, check=True)


def remove_gitmodules(proj_path: Path) -> None:
    """Deletes .gitmodules files."""
    cmd = ['find', '.', '-name', '.gitmodules', '-delete']
    subprocess.run(cmd, cwd=proj_path, check=True)


def delete_branch(proj_path: Path, branch_name: str) -> None:
    """Force delete a branch."""
    cmd = ['git', 'branch', '-D', branch_name]
    subprocess.run(cmd, cwd=proj_path, check=True)


def start_branch(proj_path: Path, branch_name: str) -> None:
    """Starts a new repo branch."""
    subprocess.run(['repo', 'start', branch_name], cwd=proj_path, check=True)


def repo_sync(proj_path: Path,) -> None:
    """Downloads new changes and updates the working files in the local environment."""
    subprocess.run(['repo', 'sync', '.'], cwd=proj_path, check=True)


def commit(proj_path: Path, message: str, no_verify: bool) -> None:
    """Commits changes."""
    cmd = ['git', 'commit', '-m', message] + (['--no-verify'] if no_verify is True else [])
    subprocess.run(cmd, cwd=proj_path, check=True)


def commit_amend(proj_path: Path) -> None:
    """Commits changes."""
    cmd = ['git', 'commit', '--amend', '--no-edit']
    subprocess.run(cmd, cwd=proj_path, check=True)


def checkout(proj_path: Path, branch_name: str) -> None:
    """Checkouts a branch."""
    cmd = ['git', 'checkout', branch_name]
    subprocess.run(cmd, cwd=proj_path, check=True)


def detach_to_android_head(proj_path: Path) -> None:
    """Detaches the project HEAD back to the manifest revision."""
    # -d detaches the project back to the manifest revision without updating.
    # -l avoids fetching new revisions from the remote. This might be superfluous with
    # -d, but I'm not sure, and it certainly doesn't harm anything.
    subprocess.run(['repo', 'sync', '-l', '-d', proj_path], cwd=proj_path, check=True)


def push(proj_path: Path, has_errors: bool) -> None:
    """Pushes change to remote."""
    remote_name = determine_remote_name(proj_path)
    cmd = ['git', 'push', remote_name, 'HEAD:refs/for/main', '-o', 'banned-words~skip']
    if revs := reviewers.find_reviewers(str(proj_path)):
        cmd.extend(['-o', revs])
    if tag := hashtags.find_hashtag(proj_path):
        cmd.extend(['-o', 't=' + tag])
    if has_errors:
        cmd.extend(['-o', 'l=Verified-1'])
    subprocess.run(cmd, cwd=proj_path, check=True)


def reset_hard(proj_path: Path) -> None:
    """Resets current HEAD and discards changes to tracked files."""
    cmd = ['git', 'reset', '--hard']
    subprocess.run(cmd, cwd=proj_path, check=True)


def clean(proj_path: Path) -> None:
    """Removes untracked files and directories."""
    cmd = ['git', 'clean', '-fdx']
    subprocess.run(cmd, cwd=proj_path, check=True)


def is_valid_url(proj_path: Path, url: str) -> bool:
    cmd = ['git', "ls-remote", url]
    return subprocess.run(cmd, cwd=proj_path, check=False, stdin=subprocess.DEVNULL,
                          stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
                          start_new_session=True).returncode == 0


def list_remote_tags(proj_path: Path, remote_name: str) -> list[str]:
    """Lists tags in a remote repository."""
    cmd = ['git', "ls-remote", "--tags", remote_name]
    out = subprocess.run(cmd, capture_output=True, cwd=proj_path, check=True,
                         text=True).stdout
    lines = out.splitlines()
    return lines


def diff_stat(proj_path: Path, diff_filter: str, revision: str) -> str:
    try:
        cmd = ['git', 'diff', revision, '--stat', f'--diff-filter={diff_filter}']
        out = subprocess.run(cmd, capture_output=True, cwd=proj_path,
                             check=True, text=True).stdout
        return out
    except subprocess.CalledProcessError as err:
        return f"Could not calculate the diff: {err}"


def diff_name_only(proj_path: Path, diff_filter: str, revision: str) -> str:
    try:
        cmd = ['git', 'diff', revision, '--name-only', f'--diff-filter={diff_filter}']
        out = subprocess.run(cmd, capture_output=True, cwd=proj_path,
                             check=True, text=True).stdout
        return out
    except subprocess.CalledProcessError as err:
        return f"Could not calculate the diff: {err}"


def is_ancestor(proj_path: Path, ancestor: str, child: str) -> bool:
    cmd = ['git', 'merge-base', '--is-ancestor', ancestor, child]
    # https://git-scm.com/docs/git-merge-base#Documentation/git-merge-base.txt---is-ancestor
    # Exit status of 0 means yes, 1 means no, and all others mean an error occurred.
    # Although a commit is an ancestor of itself, we don't want to return True
    # if ancestor points to the same commit as child.
    if get_sha_for_branch(proj_path, ancestor) == child:
        return False
    try:
        subprocess.run(
            cmd,
            cwd=proj_path,
            text=True,
            stderr=subprocess.STDOUT,
            check=True,
            stdout=subprocess.PIPE
        )
        return True
    except subprocess.CalledProcessError as ex:
        if ex.returncode == 1:
            return False
        raise


def list_branches_with_commit(proj_path: Path, commit: str, remote_name: str) -> list[str]:
    """Lists upstream branches which contain the specified commit"""
    cmd = ['git', 'branch', '-r', '--contains', commit]
    out = subprocess.run(cmd, capture_output=True, cwd=proj_path, check=True,
                         text=True).stdout
    lines = out.splitlines()
    remote_branches = [line for line in lines if remote_name in line]
    return remote_branches


def determine_remote_name(proj_path: Path) -> str:
    """Returns the remote name in the manifest."""
    root = fileutils.find_tree_containing(proj_path)
    manifest = Manifest.for_tree(root)
    return manifest.remote
