# Copyright 2020 The Pigweed Authors
#
# 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
#
#     https://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.
"""Install and check status of Git repository-based packages."""

import os
import pathlib
import shutil
import subprocess
from typing import Union
import urllib.parse

import pw_package.package_manager

PathOrStr = Union[pathlib.Path, str]


def git_stdout(*args: PathOrStr,
               show_stderr=False,
               repo: PathOrStr = '.') -> str:
    return subprocess.run(['git', '-C', repo, *args],
                          stdout=subprocess.PIPE,
                          stderr=None if show_stderr else subprocess.DEVNULL,
                          check=True).stdout.decode().strip()


def git(*args: PathOrStr,
        repo: PathOrStr = '.') -> subprocess.CompletedProcess:
    return subprocess.run(['git', '-C', repo, *args], check=True)


class GitRepo(pw_package.package_manager.Package):
    """Install and check status of Git repository-based packages."""
    def __init__(self, url, *args, commit='', tag='', **kwargs):
        super().__init__(*args, **kwargs)
        if not (commit or tag):
            raise ValueError('git repo must specify a commit or tag')

        self._url = url
        self._commit = commit
        self._tag = tag

    def status(self, path: pathlib.Path) -> bool:
        if not os.path.isdir(path / '.git'):
            return False

        remote = git_stdout('remote', 'get-url', 'origin', repo=path)
        url = urllib.parse.urlparse(remote)
        if url.scheme == 'sso' or '.git.corp.google.com' in url.netloc:
            host = url.netloc.replace(
                '.git.corp.google.com',
                '.googlesource.com',
            )
            if not host.endswith('.googlesource.com'):
                host += '.googlesource.com'
            remote = 'https://{}{}'.format(host, url.path)

        commit = git_stdout('rev-parse', 'HEAD', repo=path)
        if self._commit and self._commit != commit:
            return False

        if self._tag:
            tag = git_stdout('describe', '--tags', repo=path)
            if self._tag != tag:
                return False

        status = git_stdout('status', '--porcelain=v1', repo=path)
        return remote == self._url and not status

    def install(self, path: pathlib.Path) -> None:
        # If already installed and at correct version exit now.
        if self.status(path):
            return

        # Otherwise delete current version and clone again.
        if os.path.isdir(path):
            shutil.rmtree(path)

        # --filter=blob:none means we don't get history, just the current
        # revision. If we later run commands that need history it will be
        # retrieved on-demand. For small repositories the effect is negligible
        # but for large repositories this should be a significant improvement.
        if self._commit:
            git('clone', '--filter=blob:none', self._url, path)
            git('reset', '--hard', self._commit, repo=path)
        elif self._tag:
            git('clone', '-b', self._tag, '--filter=blob:none', self._url,
                path)
