# 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
from typing import Dict, List, Tuple


def _run(cmd: List[str], cwd: Path) -> str:
    """Runs a command and returns its output."""
    return subprocess.check_output(cmd, text=True, cwd=cwd)


def fetch(proj_path: Path, remote_names: List[str]) -> None:
    """Runs git fetch.

    Args:
        proj_path: Path to Git repository.
        remote_names: Array of string to specify remote names.
    """
    _run(['git', 'fetch', '--multiple'] + remote_names, cwd=proj_path)


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.
    """
    _run(['git', 'remote', 'add', name, url], cwd=proj_path)


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


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])

    out = _run(['git', 'remote', '-v'], proj_path)
    lines = out.splitlines()
    return dict([parse_remote(line) for line in lines])


def get_sha_for_branch(proj_path: Path, branch: str):
    """Gets the hash SHA for a branch."""
    return _run(['git', 'rev-parse', branch], proj_path).strip()


def get_commits_ahead(proj_path: Path, branch: str,
                      base_branch: str) -> List[str]:
    """Lists commits in `branch` but not `base_branch`."""
    out = _run([
        'git', 'rev-list', '--left-only', '--ancestry-path', '{}...{}'.format(
            branch, base_branch)
    ], proj_path)
    return out.splitlines()


def get_commit_time(proj_path: Path, commit: str) -> datetime.datetime:
    """Gets commit time of one commit."""
    out = _run(['git', 'show', '-s', '--format=%ct', commit], cwd=proj_path)
    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."""
    lines = _run(['git', 'branch', '-r'], cwd=proj_path).splitlines()
    stripped = [line.strip() for line in lines]
    remote_path = remote_name + '/'
    return [
        line.lstrip(remote_path) for line in stripped
        if line.startswith(remote_path)
    ]


def list_remote_tags(proj_path: Path, remote_name: str) -> List[str]:
    """Lists all tags for a remote."""
    def parse_remote_tag(line: str) -> str:
        tag_prefix = 'refs/tags/'
        tag_suffix = '^{}'
        line = line[line.index(tag_prefix):]
        return line.lstrip(tag_prefix).rstrip(tag_suffix)

    lines = _run(['git', "ls-remote", "--tags", remote_name],
                 cwd=proj_path).splitlines()
    tags = [parse_remote_tag(line) for line in lines]
    return list(set(tags))


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


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:
        _run(['git', 'merge', branch, '--no-commit'], cwd=proj_path)
    except subprocess.CalledProcessError:
        # Merge failed. Error is already written to console.
        _run(['git', 'merge', '--abort'], cwd=proj_path)
        raise


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


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


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


def commit(proj_path: Path, message: str) -> None:
    """Commits changes."""
    _run(['git', 'commit', '-m', message], cwd=proj_path)


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


def push(proj_path: Path, remote_name: str) -> None:
    """Pushes change to remote."""
    _run(['git', 'push', remote_name, 'HEAD:refs/for/master'], cwd=proj_path)
