# 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.

import logging
import os
import subprocess

LOG = logging.getLogger(__name__)

GIT_SUFFIX = ".git"


class GitCommandException(Exception):
    """Exception thrown by failed git commands."""


def git_dir():
    try:
        return (
            subprocess.run(
                ["git", "rev-parse", "--git-dir"], capture_output=True, check=True
            )
            .stdout.decode()
            .strip()
        )
    except subprocess.CalledProcessError:
        raise GitCommandException("Unable to find .git directory.")


def commit_id(repo_dir, ref="HEAD"):
    try:
        cmd = ["git", "rev-parse", "--short", ref]
        return (
            subprocess.run(cmd, cwd=repo_dir, capture_output=True, check=True)
            .stdout.decode()
            .strip()
        )
    except subprocess.CalledProcessError:
        raise GitCommandException("Unable to parse current commit ID.")


def add(repo_dir, files=None):
    if not files:
        files = ["."]
    try:
        cmd = ["git", "add"]
        cmd.extend(files)
        subprocess.run(cmd, cwd=repo_dir, capture_output=True, check=True)
    except subprocess.CalledProcessError:
        raise GitCommandException("Unable to add files to index.")


def commit(repo_dir, message):
    try:
        cmd = ["git", "commit", "-m", message]
        subprocess.run(cmd, cwd=repo_dir, capture_output=True, check=True)
    except subprocess.CalledProcessError:
        raise GitCommandException("Unable to commit.")


def push(repo_dir, remote, refspec):
    try:
        cmd = ["git", "push", remote, refspec]
        subprocess.run(cmd, cwd=repo_dir, capture_output=True, check=True)
    except subprocess.CalledProcessError:
        raise GitCommandException("Unable to push.")


def clone(url, target_dir=""):
    try:
        cmd = ["git", "clone", url, target_dir]
        subprocess.run(cmd, capture_output=True, check=True)
        if target_dir:
            return target_dir

        repo_name = url.split("/")[-1]
        if repo_name.endswith(GIT_SUFFIX):
            repo_name = repo_name[: -len(GIT_SUFFIX)]
        return repo_name
    except subprocess.CalledProcessError:
        raise GitCommandException(f"Unable to clone repo {url}.")


def init(base_dir, repo_name, bare=False):
    try:
        cmd = ["git", "init"]
        if bare:
            cmd.append("--bare")
        cmd.append(os.path.join(base_dir, repo_name))
        subprocess.run(cmd, cwd=base_dir, capture_output=True, check=True)
    except subprocess.CalledProcessError:
        raise GitCommandException(f"Unable to initialize git repo {repo_name}.")


def pack_refs(repo_dir, all=False):
    command = "git pack-refs"
    if all:
        command += " --all"
    try:
        subprocess.run(command, cwd=repo_dir, shell=True, check=True)
    except subprocess.CalledProcessError as e:
        if e.stdout:
            LOG.info(e.stdout)
        if e.stderr:
            LOG.error(e.stderr)
        raise GitCommandException(f"Failed to pack refs in {repo_dir}")


def gc(repo_dir, git_config=None, args=None):
    cmd = "git "
    if git_config:
        cmd = cmd + "-c " + " -c ".join(git_config)
    cmd += " gc"
    if args:
        cmd = cmd + " " + " ".join(args)
    try:
        # Git gc requires a shell to output logs, i.e. `shell` has to be `True`
        subprocess.run(cmd, cwd=repo_dir, shell=True, check=True)
    except subprocess.CalledProcessError as e:
        if e.stdout:
            LOG.info(e.stdout)
        if e.stderr:
            LOG.error(e.stderr)
        raise GitCommandException(f"Failed to run gc in {repo_dir}")
