#!/usr/bin/env python
"""
Git functions.
"""

import logging
import pathlib
import subprocess


LOGGER = logging.getLogger(__name__)


class GitlabRepo:
    """
    Basic functionality for retrieving Git information.
    """

    def __init__(self, path, remote="origin"):
        """
        Args:
            path:
                A path to the Git repository or any non-submodule path within
                it.

            remote:
                The remote repository name to use for generating URLs.
        """
        self.path = pathlib.Path(path).resolve()
        self.path = self.top_level
        self.remote = remote
        self._origin_url = None

    def run_cmd(self, cmd):
        """
        Run a git command and return its output.

        Args:
            cmd:
                The git sub-command and arguments.

        Returns:
            The command output.
        """
        cmd = ("git", "-C", str(self.path), *cmd)
        LOGGER.debug("Running command: %s", cmd)
        return (
            subprocess.run(cmd, check=True, capture_output=True).stdout.decode().strip()
        )

    @property
    def top_level(self):
        """
        The top-level directory.
        """
        path = self.run_cmd(("rev-parse", "--show-toplevel"))
        return pathlib.Path(path).resolve()

    @property
    def remote_url(self):
        """
        The origin URL.
        """
        if self._origin_url is None:
            self._origin_url = self.run_cmd(("config", "--get", "remote.origin.url"))
        return self._origin_url

    @property
    def parsed_origin(self):
        """
        A 3-tuple of the origin's host, namespace and project name.
        """
        host, subpath = self.remote_url.split(":", 1)
        subpath = subpath.rsplit(".", 1)[0]
        namespace, name = subpath.split("/", 1)
        host = host.split("@", 1)[1]
        return host, namespace, name

    @property
    def public_url(self):
        """
        The URL for the main project page.
        """
        host, namespace, name = self.parsed_origin
        return f"https://{host}/{namespace}/{name}"

    def get_section_url(self, section):
        """
        The URL to one of the various GitLab sections, e.g. "blob/main" or
        "packages".
        """
        section = section.lstrip()
        return f"{self.public_url}/-/{section}"

    @property
    def public_git_url(self):
        """
        The publically accessible HTTPS URL.
        """
        return f"{self.public_url}.git"

    def get_main_blob_url(self, path):
        """
        Get the main branch URL to the given path.
        """
        path = path.lstrip("/")
        return self.get_section_url(f"blob/main/{path}")

    @property
    def readme_url(self):
        """
        The URL to the README.
        """
        return self.get_main_blob_url("README.md")

    def get_gitlab_project(self, glab):
        """
        Get the python-gitlab Project instance from a python-gitlab GitLab
        instance.
        """
        _host, namespace, name = self.parsed_origin
        return glab.projects.get(f"{namespace}/{name}")
