# Copyright 2019 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.
"""Test API for checkout."""

from recipe_engine import recipe_test_api

REPO = 'https://pigweed.googlesource.com/pigweed/pigweed'
MANIFEST_REPO = 'https://pigweed.googlesource.com/manifest'

DEFAULT_MANIFEST = """
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
  <remote
    name="default_remote"
    fetch="sso://default"
    />

  <remote
    name="pigweed_remote"
    revision="master"
    fetch="https://pigweed.googlesource.com"
    review="https://pigweed-review.googlesource.com"
    />

  <remote
    name="pigweed-internal_remote"
    revision="master"
    fetch="https://pigweed-internal.googlesource.com"
    review="https://pigweed-internal-review.googlesource.com"
    />

  <default
    remote="default_remote"
    revision="master"
    />

  <project
    name="default_name"
    path="default_path"
    />

  <project
    name="pigweed_name"
    path="pigweed_path"
    remote="pigweed_remote"
    revision="master"
    />

  <project
    name="pigweed-internal_name"
    path="pigweed-internal_path"
    remote="pigweed-internal_remote"
    />
</manifest>
""".strip()


class CheckoutTestApi(recipe_test_api.RecipeTestApi):
  """Test API for checkout."""

  @property
  def manifest_repo(self):
    return MANIFEST_REPO

  def git_properties(self, remote=REPO, branch='master', use_repo=False):
    return {
        '$pigweed/checkout': {
            'remote': remote,
            'branch': branch,
            'use_repo': use_repo,
        },
    }

  def repo_properties(self, remote=MANIFEST_REPO, use_repo=True, **kwargs):
    return self.git_properties(remote=remote, use_repo=use_repo, **kwargs)

  def ci_test_data(self, git_repo=REPO, **kwargs):
    return self.m.buildbucket.ci_build(git_repo=git_repo, **kwargs)

  def try_test_data(self, git_repo=REPO, **kwargs):
    return self.m.buildbucket.try_build(git_repo=git_repo, **kwargs)

  def manifest_test_data(self, name='manifest', raw_xml=DEFAULT_MANIFEST):
    return self.step_data('checkout {}.read manifest.read file'.format(name),
                          self.m.file.read_text(raw_xml))

  def root_files(self, *files, **kwargs):
    name = kwargs.pop('name', 'manifest')
    assert not kwargs
    files = set(files)
    files.add('.repo')
    return self.step_data(
        'checkout {}.ls'.format(name),
        stdout=self.m.raw_io.output(
            ''.join(('{}\n'.format(x) for x in sorted(files)))))

  def submodules(self, root_name='pigweed',
                 checkout_root='[START_DIR]/checkout',
                 raw_submodule_status=None,
                 **submodules):
    # kwargs = { path: remote } (e.g., 'foo': 'https://x.googlesource.com/foo')
    output = raw_submodule_status or ''.join(
        '{} {} ({})\n'.format('a' * 40, path, 'foo') for path in submodules
    )
    res = self.override_step_data(
        'checkout {}.git submodule status'.format(root_name),
        stdout=self.m.raw_io.output(output))
    for path, remote in submodules.iteritems():
      res += self.step_data(
          'checkout {}.parse_submodules.git origin {}/{}'.format(
              root_name, checkout_root, path),
          stdout=self.m.raw_io.output(remote))

    return res
