# -*- coding: utf-8 -*-
# Copyright 2020 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Copied from
# https://chromium.googlesource.com/chromiumos/infra/recipes/+/HEAD/recipe_modules/repo/
"""API for working with the 'repo' VCS tool.

See: https://chromium.googlesource.com/external/repo/
"""

import collections
import os
import types
from xml.etree import cElementTree as ElementTree

from recipe_engine import recipe_api

MANIFEST_MOCK = """
    <manifest>
      <project path="SAMPLE" revision="FROM_REV"/>
    </manifest>
  """

ManifestDiff = collections.namedtuple(
    'ManifestDiff', ['name', 'path', 'from_rev', 'to_rev']
)

ProjectInfo = collections.namedtuple(
    'ProjectInfo', ['name', 'path', 'remote', 'branch']
)

_REPO_URL = 'https://pigweed.googlesource.com/third_party/gerrit/git-repo'
_REPO_REV = 'b750b48f50eb4a11087ca6775161d5bf4d5c47d5'


class RepoApi(recipe_api.RecipeApi):
    """A module for interacting with the repo tool."""

    ManifestDiff = ManifestDiff  # pylint: disable=invalid-name

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._repo = None

    @property
    def repo(self):
        return self.resource('repo')

    def _find_root(self):
        """Starting from cwd, find an ancestor with a '.repo' subdir."""
        # We need a copy of cwd that we can modify. join() with no arguments
        # returns the instance, so we add an element, and then remove it.
        candidate = self.m.context.cwd
        while candidate.pieces:
            if self.m.path.exists(candidate / '.repo'):
                return candidate
            candidate = self.m.path.dirname(candidate)
        return None

    def _step(self, args, name=None, attempts=1, **kwargs):
        """Executes 'repo' with the supplied arguments.

        Args:
          args (list): A list of arguments to supply to 'repo'.
          name (str): The name of the step. If None, generate from the args.
          attempts (int): Number of attempts.
          **kwargs: See 'step.__call__'.

        Returns:
          StepData: See 'step.__call__'.
        """
        if name is None:
            name = 'repo'
            # Add first non-flag argument to name.
            for arg in args:
                if isinstance(arg, str) and arg[:1] != '-':
                    name += ' ' + arg
                    break
        kwargs.setdefault('infra_step', True)
        for i in range(attempts):
            try:
                return self.m.step(name, [self.repo] + args, **kwargs)
            except self.m.step.StepFailure:
                if i == attempts - 1:
                    raise

    def _clear_git_locks(self):
        """Removes any git locks found in the entire repo checkout."""

        repo_cmd = [
            'find',
            '.repo/',
            '-type',
            'f',
            '-name',
            '*.lock',
            '-print',
            '-delete',
        ]
        self.m.step('clear repo locks', repo_cmd, infra_step=True)

        try:
            git_cmd = [
                'forall',
                '--ignore-missing',
                '-j',
                '32',
                '-c',
                'find',
                '.git/',
                '-type',
                'f',
                '-name',
                '*.lock',
                '-print',
                '-delete',
            ]
            self._step(git_cmd, 'clear git locks')
        except recipe_api.StepFailure:  # pragma: nocover
            # try again without the --ignore-missing
            git_cmd = [
                'forall',
                '-j',
                '32',
                '-c',
                'find',
                '.git/',
                '-type',
                'f',
                '-name',
                '*.lock',
                '-print',
                '-delete',
            ]
            self._step(git_cmd, 'retry clear git locks')

    def init(  # pylint: disable=invalid-name
        self,
        manifest_url,
        _kwonly=(),
        manifest_branch=None,
        manifest_name=None,
        reference=None,
        groups=None,
        depth=None,
        repo_url=_REPO_URL,
        repo_rev=_REPO_REV,
        timeout=15 * 60,
        **kwargs,
    ):
        """Executes 'repo init' with the given arguments.

        Args:
            manifest_url (str): URL of the manifest repository to clone.
            _kwonly: Fake argument.
            manifest_branch (str): Manifest repository branch to checkout.
            manifest_name (str): Manifest file to use.
            reference (str): Location of a mirror directory to bootstrap sync.
            groups (list): Groups to checkout (see `repo init --groups`).
            depth (int): Create a shallow clone of the given depth.
            repo_url (str): URL of the repo repository.
            repo_rev (str): Repo binary revision to use.
            timeout (int): Timeout in seconds.
            **kwargs: Passed through to self.m.step().
        """
        assert (
            _kwonly == ()
        ), (  # pylint: disable=g-explicit-bool-comparison
            'init accepts only 1 positional arg'
        )
        cmd = ['init', '--manifest-url', manifest_url, '--groups', 'all']
        if manifest_branch is not None:
            cmd += ['--manifest-branch', manifest_branch]
        if reference is not None:
            cmd += ['--reference', reference]
        if groups is not None:
            assert not isinstance(groups, str)
            cmd += ['--groups', ','.join(groups)]
        if depth is not None:
            cmd += ['--depth', '%d' % depth]
        if repo_url is not None:
            cmd += ['--repo-url', repo_url]
        if repo_rev is not None:
            cmd += ['--repo-rev', repo_rev, '--no-repo-verify']
        if manifest_name:
            cmd += ['--manifest-name', manifest_name]
        self._step(cmd, timeout=timeout, **kwargs)
        self._clear_git_locks()

        if self.m.context.cwd:
            self.m.path.mock_add_paths(self.m.context.cwd / '.repo')

    def sync(  # pylint: disable=invalid-name
        self,
        _kwonly=(),
        force_sync=False,
        detach=False,
        current_branch=False,
        jobs=None,
        manifest_name=None,
        no_tags=False,
        optimized_fetch=False,
        cache_dir=None,
        timeout=None,
        attempts=1,
        verbose=True,
        **kwargs,
    ):
        """Executes 'repo sync' with the given arguments.

        Args:
          _kwonly: Fake argument.
          force_sync (bool): Overwrite existing git directories if needed.
          detach (bool): Detach projects back to manifest revision.
          current_branch (bool): Fetch only current branch.
          jobs (int): Projects to fetch simultaneously.
          manifest_name (str): Temporary manifest to use for this sync.
          no_tags (bool): Don't fetch tags.
          optimized_fetch (bool): Only fetch projects if revision doesn't exist.
          cache_dir (Path): Use git-cache with this cache directory.
          timeout (int): Timeout in seconds.
          attempts (int): Number of attempts.
          verbose (bool): Show all output.
          **kwargs: Passed through to self.m.step().
        """
        assert (
            _kwonly == ()
        ), (  # pylint: disable=g-explicit-bool-comparison
            'init accepts only 1 positional arg'
        )
        cmd = ['sync']
        if force_sync:
            cmd += ['--force-sync']
        if detach:
            cmd += ['--detach']
        if current_branch:
            cmd += ['--current-branch']
        if jobs is not None:
            cmd += ['--jobs', '%d' % jobs]
        if manifest_name is not None:
            cmd += ['--manifest-name', manifest_name]
        if no_tags:
            cmd += ['--no-tags']
        if optimized_fetch:
            cmd += ['--optimized-fetch']
        if cache_dir is not None:
            cmd += ['--cache-dir', cache_dir]
        if verbose:
            cmd += ['--verbose']

        # Doing retry logic here instead of using that in _step() because we
        # need to clean up the checkout or we sometimes get inconsistent
        # results.
        for i in range(attempts):
            try:
                return self._step(cmd, name=None, timeout=timeout, **kwargs)
            except self.m.step.StepFailure:
                if i == attempts - 1:
                    raise
                self._step(
                    ['forall', '-c', 'git reset --hard HEAD'], ok_ret='any'
                )

    def sync_manifest(self, manifest_data, **kwargs):
        """Sync to the given manifest file data.

        Args:
          manifest_data (str): Manifest XML data to use for the sync.
          **kwargs: Keyword arguments to pass to 'repo.sync'.
        """
        repo_root = self._find_root()
        assert repo_root is not None, 'no repo root found'

        manifest_path = self.m.path.mkstemp('manifest')
        self.m.file.write_raw('write manifest', manifest_path, manifest_data)

        repo_manifests_path = repo_root / '.repo' / 'manifests'
        manifest_relpath = os.path.relpath(
            str(manifest_path), str(repo_manifests_path)
        )
        self.sync(manifest_name=manifest_relpath, **kwargs)

    def start(self, branch, projects=None):
        """Start a new branch in the given projects, or all projects if not set.

        Args:
          branch (str): The new branch name.
          projects (list[str]): The projects for which to start a branch.
        """
        cmd = ['start', branch]
        if projects is not None:
            cmd.extend(projects)
        else:
            cmd.append('--all')
        self._step(cmd)

    def project_infos(self, projects=()):
        """Uses 'repo forall' to gather project information.

        Args:
          projects (List[str]): Project names or paths to return info for. Defaults
            to all projects.

        Returns:
          List[ProjectInfo]: Requested project infos.
        """

        def step_test_data():
            data = '\n'.join(
                f'{p}|src/{p}|cros|refs/heads/main'
                for p in projects or ['a', 'b', 'c']
            )
            return self.m.raw_io.test_api.stream_output_text(data)

        cmd = ['forall'] + list(projects)
        cmd += [
            '-c',
            r'echo $REPO_PROJECT\|$REPO_PATH\|$REPO_REMOTE\|$REPO_RREV',
        ]
        step_data = self._step(
            cmd,
            stdout=self.m.raw_io.output_text(add_output_log=True),
            step_test_data=step_test_data,
        )

        infos = []
        for line in step_data.stdout.strip().split('\n'):
            name, path, remote, rrev = line.split('|')
            branch = None
            if rrev.startswith('refs/heads/'):
                branch = rrev
            infos.append(ProjectInfo(name, path, remote, branch))
        return infos

    def project_info(self, project):
        """Use 'repo forall' to gather project information for one project.

        Args:
          project (str|Path): Project name or path to return info for.

        Returns:
          ProjectInfo: The request project info.
        """
        project_infos = self.project_infos(projects=[project])
        assert len(set(project_infos)) == 1, 'expected one project'
        return project_infos[0]

    def manifest_snapshot(self, manifest_file=None):
        """Uses repo to create a manifest snapshot and returns it as a string.

        By default uses the internal .repo manifest, but can optionally take
        another manifest to use.

        Args:
          manifest_file (Path): If given, path to alternate manifest file to use.

        Returns:
          str: The manifest XML as a string.
        """
        step_test_data = lambda: (  # pylint: disable=g-long-lambda
            self.m.raw_io.test_api.stream_output_text('<manifest></manifest>')
        )

        cmd = ['manifest', '-r']
        if manifest_file:
            cmd += ['-m', manifest_file]

        step_data = self._step(
            cmd,
            stdout=self.m.raw_io.output_text(add_output_log=True),
            step_test_data=step_test_data,
        )
        return step_data.stdout.strip()

    def diff_manifests(self, from_manifest_str, to_manifest_str):
        """Diffs the two manifests and returns an array of differences.

        Given the two manifest XML strings, generates an array of `ManifestDiff`.
        This only returns **CHANGED** projects, it skips over projects that were
        added or deleted.

        Args:
          from_manifest_str (str): The from manifest XML string
          to_manifest_str (str): The to manifest XML string.

        Returns:
          List[ManifestDiff]: An array of `ManifestDiff` namedtuple for any existing
          changed project (excludes added/removed projects).
        """

        def project_paths(xml_data):
            xml = ElementTree.fromstring(xml_data)
            attrs = [proj.attrib for proj in xml.iterfind('project')]
            # Make sure `path` is set, use `name` if `path` is missing
            for attr in attrs:
                attr['path'] = attr.get('path', attr.get('name'))
            # Key them by path
            return {attr['path']: attr for attr in attrs}

        from_paths = project_paths(from_manifest_str)
        to_paths = project_paths(to_manifest_str)
        changes = []
        for from_path, from_attrs in from_paths.items():
            if from_path not in to_paths:
                # Project was deleted, we don't care. Move on, nothing to see here!
                continue
            from_name = from_attrs['name']
            from_revision = from_attrs['revision']
            to_revision = to_paths[from_path]['revision']
            if from_revision == to_revision:
                # The revision didn't change (aka no CLs landed between the last
                # snapshot and this one for that path.
                continue
            changes.append(
                ManifestDiff(from_name, from_path, from_revision, to_revision)
            )
        return changes

    def diff_manifests_informational(
        self, old_manifest_path, new_manifest_path
    ):
        """Informational step that logs a "manifest diff".

        Args:
          old_manifest_path (Path): Path to old manifest file.
          new_manifest_path (Path): Path to new manifest file.
        """
        name = 'manifest diff'
        # Manifest paths must be relative to the current repo .repo/manifests dir.
        repo_root = self._find_root()
        if repo_root is None:
            step = self.m.step(name, [])
            step.presentation.step_text = (
                'manifest diff failed; no repo root found'
            )
            return
        manifests_dir = self.m.path.abspath(repo_root / '.repo' / 'manifests')

        cmd = [
            'diffmanifests',
            os.path.relpath(str(old_manifest_path), manifests_dir),
            os.path.relpath(str(new_manifest_path), manifests_dir),
        ]
        self._step(cmd, name=name)

    def _git_clean_checkout(self, root_path):
        """Ensure the given repo does not contain untracked files or directories.

        We're assuming that the root path provided has already been validated.

        Args:
          root_path (Path): Path to the repo root.
        """
        with self.m.step.nest('ensure clean checkout'):
            with self.m.context(cwd=root_path, infra_steps=True):
                cmd = [
                    'forall',
                    '--ignore-missing',
                    '-j',
                    '32',
                    '-c',
                    'git',
                    'clean',
                    '-d',
                    '-f',
                ]
                self._step(
                    cmd, stdout=self.m.raw_io.output_text(add_output_log=True)
                )

    def ensure_synced_checkout(
        self, root_path, manifest_url, init_opts=None, sync_opts=None
    ):
        """Ensure the given repo checkout exists and is synced.

        Args:
          root_path (Path): Path to the repo root.
          manifest_url (str): Manifest URL for 'repo.init`.
          init_opts (dict): Extra keyword arguments to pass to 'repo.init'.
          sync_opts (dict): Extra keyword arguments to pass to 'repo.sync'.
        """
        with self.m.step.nest('ensure synced checkout'):
            self.m.file.ensure_directory('ensure root path', root_path)
            with self.m.context(cwd=root_path, infra_steps=True):
                for retries in range(2):
                    try:
                        # Remove .repo/manifests and .repo/manifests.git to avoid potential
                        # problems when switching to a different manifest repo or branch.
                        for manifest_dir in ('manifests', 'manifests.git'):
                            self.m.file.rmtree(
                                f'remove .repo/{manifest_dir}',
                                root_path / '.repo' / manifest_dir,
                            )

                        self.init(manifest_url, **(init_opts or {}))
                        self._git_clean_checkout(root_path)
                        self._binary_selfupdate(root_path)
                        self.sync(**(sync_opts or {}))
                        break
                    except recipe_api.StepFailure:
                        if retries < 1:
                            self.m.file.rmcontents(
                                'clean up root path and retry', root_path
                            )
                        else:
                            raise

            # Sanity check since `repo init` will happily reuse a repository in the
            # cwd's ancestor directories.
            assert self.m.path.exists(root_path / '.repo'), '.repo not created!'

    def _binary_selfupdate(self, root_path):
        """Issues a repo selfupdate to update the binary.

        Args:
          root_path (Path): Path to the repo root.
        """
        with self.m.step.nest('repo binary update'):
            with self.m.context(cwd=root_path, infra_steps=True):
                cmd = ['selfupdate']
                self._step(cmd, ok_ret='any')
