# Copyright 2018 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from recipe_engine.recipe_api import Property
import collections

DEPS = [
    'infra/checkout',
    'recipe_engine/buildbucket',
    'recipe_engine/json',
    'recipe_engine/properties',
    'recipe_engine/path',
]

PROPERTIES = {
    'project':
        Property(kind=str, help='The git project', default='garnet'),
    'override':
        Property(kind=bool, help='Whether to override $project', default=False),
    'checkout_from_snapshot':
        Property(kind=bool, help='Checkout from snapshot', default=False),
}


def RunSteps(api, project, override, checkout_from_snapshot):
  if checkout_from_snapshot:
    api.checkout.from_snapshot('snapshot')
  else:
    api.checkout(
        manifest='minimal',
        remote='https://fuchsia.googlesource.com/manifest',
        project=project,
        build_input=api.buildbucket.build.input,
        override=override,
    )


def GenTests(api):
  yield api.checkout.test('default')

  yield api.checkout.test(
      'global_integration_tryjob',
      properties=dict(
          project='integration',
          override=False,
          tryjob=True,
      ),
  )

  yield api.checkout.test(
      'global_integration_ci',
      properties=dict(
          project='integration',
          override=False,
          tryjob=False,
      ),
  )

  yield api.checkout.test(
      'local_integration_tryjob',
      properties=dict(
          project='garnet',
          override=True,
          tryjob=True,
      ),
  )

  yield api.checkout.test(
      'local_integration_ci',
      properties=dict(
          project='garnet',
          override=True,
          tryjob=False,
      ),
  )

  yield api.checkout.test(
      'tryjob_with_patchfile',
      properties=dict(
          project='garnet',
          tryjob=True,
      ),
      patchfile=[{
          'ref': 'refs/changes/cc/aabbcc/1',
          'host': 'example-review.googlesource.com',
          'project': 'not_garnet'
      }])

  yield api.checkout.test(
      'fail_to_patch_over_gerrit_change',
      properties=dict(
          project='garnet',
          tryjob=True,
      ),
      patchfile=[{
          'ref': 'refs/changes/cc/aabbcc/1',
          'host': 'fuchsia-review.googlesource.com',
          'project': 'garnet',
      }])

  yield api.checkout.test(
      'fail_to_patch_same_project_many_times',
      properties=dict(
          project='garnet',
          tryjob=True,
      ),
      patchfile=[{
          'ref': 'refs/changes/cc/aabbcc/1',
          'host': 'fuchsia-review.googlesource.com',
          'project': 'zircon',
      }, {
          'ref': 'refs/changes/ff/ddeeff/2',
          'host': 'fuchsia-review.googlesource.com',
          'project': 'zircon',
      }])

  yield api.checkout.test(
      'when_patchfile_host_has_protocol',
      properties=dict(
          project='garnet',
          tryjob=True,
      ),
      patchfile=[{
          'ref': 'refs/changes/cc/aabbcc/1',
          'host': 'https://fuchsia-review.googlesource.com',
          'project': 'zircon',
      }])

  yield api.checkout.test(
      'should_ignore_patches_for_non_dependant_projects',
      properties=dict(
          project='zircon',
          tryjob=True,
      ),
      patchfile=[{
          'ref': 'refs/changes/cc/aabbcc/1',
          'host': 'https://fuchsia-review.googlesource.com',
          'project': 'topaz',
      }]) + api.step_data('jiri project', api.json.output([]))

  yield api.checkout.test(
      'from_snapshot',
      properties=dict(
          project='garnet',
          tryjob=True,
          checkout_from_snapshot=True,
      ))
