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

# Copied from
# https://chromium.googlesource.com/chromiumos/infra/recipes/+/HEAD/recipe_modules/repo/
# pylint: disable=missing-module-docstring
from __future__ import annotations

from collections.abc import Iterator

from recipe_engine import recipe_api, recipe_test_api

DEPS = [
    'pigweed/repo',
    'recipe_engine/assertions',
    'recipe_engine/context',
    'recipe_engine/path',
]


def RunSteps(api: recipe_api.RecipeScriptApi):
    with api.context(cwd=api.path.cleanup_dir):
        api.assertions.assertIsNone(api.repo._find_root())  # pylint: disable=protected-access

    checkout = api.path.start_dir / 'checkout'

    with api.context(cwd=checkout):
        api.repo.init('http://manifest_url')
        api.repo.init(
            'http://manifest_url',
            manifest_branch='mybranch',
            manifest_name='pigweed.xml',
            reference='/preload/chromeos',
            groups=['group1', 'group2'],
            depth=10,
            repo_url='http://repo_url',
            repo_rev='next',
            clone_bundle=False,
        )
        api.repo.sync()
        api.repo.sync(
            force_sync=True,
            detach=True,
            current_branch=True,
            jobs=99,
            manifest_name='snapshot.xml',
            no_tags=True,
            optimized_fetch=True,
            cache_dir='/tmp/cache',
        )

        api.repo.sync_manifest('<manifest></manifest>')

    infos = api.repo.project_infos()
    api.assertions.assertEqual(len(infos), 3)
    api.assertions.assertEqual(infos[0].path, 'src/a')

    info = api.repo.project_info(project='foo')
    api.assertions.assertEqual(info.name, 'foo')

    api.assertions.assertEqual(
        api.repo.manifest_snapshot(), '<manifest></manifest>'
    )
    api.assertions.assertEqual(
        api.repo.manifest_snapshot('some_manifest_file'),
        '<manifest></manifest>',
    )

    snapshot_a = checkout / 'snapshot_a.xml'
    snapshot_b = checkout / 'snapshot_b.xml'
    with api.context(cwd=api.path.cleanup_dir):
        api.repo.diff_manifests_informational(snapshot_a, snapshot_b)

    repo_root = api.path.start_dir / 'repo'
    api.path.mock_add_paths(repo_root / '.repo')
    with api.context(cwd=repo_root / 'subdir'):
        api.repo.diff_manifests_informational(snapshot_a, snapshot_b)

    from_manifest = """
    <manifest>
      <project name="NAME" path="PATH" revision="FROM_REV"/>
      <project name="NO_CHANGE" revision="NO_CHANGE_REV"/>
      <project name="DELETED" revision="REV"/>
    </manifest>
  """

    to_manifest = """
    <manifest>
      <project name="NAME" path="PATH" revision="TO_REV"/>
      <project name="NO_CHANGE" revision="NO_CHANGE_REV"/>
    </manifest>
  """

    [diff] = api.repo.diff_manifests(from_manifest, to_manifest)
    api.assertions.assertEqual(diff.name, 'NAME')
    api.assertions.assertEqual(diff.path, 'PATH')
    api.assertions.assertEqual(diff.from_rev, 'FROM_REV')
    api.assertions.assertEqual(diff.to_rev, 'TO_REV')

    api.repo.ensure_synced_checkout(
        api.path.cleanup_dir / 'ensure', 'http://manifest_url'
    )

    api.repo.start('no-projects')
    api.repo.start('with-projects', projects=['project'])


def GenTests(api) -> Iterator[recipe_test_api.TestData]:
    yield api.test('setup_repo')
