# 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='',
                 sparse_list=None,
                 **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
        self._sparse_list = sparse_list

    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

        # If it is a sparse checkout, sparse list shall match.
        if self._sparse_list:
            if not self.check_sparse_list(path):
                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)

        if self._sparse_list:
            self.checkout_sparse(path)
        else:
            self.checkout_full(path)

    def checkout_full(self, path: pathlib.Path) -> None:
        # --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)

    def checkout_sparse(self, path: pathlib.Path) -> None:
        # sparse checkout
        git('init', path)
        git('remote', 'add', 'origin', self._url, repo=path)
        git('config', 'core.sparseCheckout', 'true', repo=path)

        # Add files to checkout by editing .git/info/sparse-checkout
        with open(path / '.git' / 'info' / 'sparse-checkout', 'w') as sparse:
            for source in self._sparse_list:
                sparse.write(source + '\n')

        # Either pull from a commit or a tag.
        target = self._commit if self._commit else self._tag
        git('pull', '--depth=1', 'origin', target, repo=path)

    def check_sparse_list(self, path: pathlib.Path) -> bool:
        sparse_list = git_stdout('sparse-checkout', 'list',
                                 repo=path).strip('\n').splitlines()
        return set(sparse_list) == set(self._sparse_list)
