# 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 google.protobuf import json_format

from recipe_engine.config import List
from recipe_engine.recipe_api import Property

from PB.infra.fuchsia import Fuchsia

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

PROPERTIES = {
    'project':
        Property(
            kind=str,
            help='The name of that jiri should assign to the project',
            default='garnet'),
    'remote':
        Property(
            kind=str,
            help='The remote URL of the manifest repo',
            default='https://fuchsia.googlesource.com/manifest'),
    'manifest':
        Property(
            kind=str,
            help='The name of the manifest to import from the integration repo',
            default='minimal'),
    'use_snapshot':
        Property(kind=bool, help='Checkout from snapshot', default=False),
    'is_release_version':
        Property(
            kind=bool,
            help='Whether or not checkout is a release version',
            default=False),
    'attributes':
        Property(
            kind=List(str),
            help='Attributes corresponding to optional packages or projects '
            'to checkout',
            default=()),
}


def RunSteps(api, project, remote, manifest, use_snapshot, is_release_version,
             attributes):
  checkout_spec = Fuchsia.Checkout(
      project=project,
      remote=remote,
      manifest=manifest,
      use_snapshot=use_snapshot,
      is_release_version=is_release_version,
      attributes=attributes,
  )
  checkout = api.checkout.from_spec(checkout_spec)
  assert checkout.root_dir
  assert checkout.snapshot_file
  checkout.checkout_snapshot  # pylint: disable=pointless-statement
  checkout.release_version  # pylint: disable=pointless-statement
  checkout.upload_results('gcs_bucket')


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

  yield api.checkout.test(
      'global_integration_tryjob',
      properties=dict(project='integration',),
  )

  yield api.checkout.test(
      'global_integration_ci',
      properties=dict(
          project='integration',
          bucket='global',
      ),
  ) + api.buildbucket.ci_build(
      git_repo='https://fuchsia.googlesource.com/integration')

  yield api.checkout.test(
      'global_integration_release_ci',
      tryjob=False,
      properties=dict(
          project='integration',
          bucket='global',
          is_release_version=True,
          attributes=['attr1', 'attr2'],
      ),
  ) + api.buildbucket.ci_build(
      git_repo='https://fuchsia.googlesource.com/integration') + api.step_data(
          'checkout.git describe',
          api.raw_io.stream_output('releases/0.20190603.0.0'))

  yield api.checkout.test(
      'global_integration_release_ci_invalid_tag',
      status='failure',
      tryjob=False,
      properties=dict(
          project='integration',
          bucket='global',
          is_release_version=True,
      ),
  ) + api.buildbucket.ci_build(
      git_repo='https://fuchsia.googlesource.com/integration') + api.step_data(
          'checkout.git describe', api.raw_io.stream_output('invalidtag'))

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

  yield api.checkout.test(
      'local_integration_tryjob_patch_failure',
      status='infra_failure',
      properties=dict(project='garnet',)) + api.step_data(
          'checkout.jiri patch', retcode=1)

  yield api.checkout.test(
      'local_integration_tryjob_patch_rebase_failure',
      status='failure',
      properties=dict(project='garnet',),
  ) + api.step_data(
      'checkout.jiri patch', retcode=api.jiri.RebaseError.EXIT_CODE)

  yield api.checkout.test(
      'local_integration_ci',
      tryjob=False,
  ) + api.buildbucket.ci_build(
      git_repo='https://fuchsia.googlesource.com/not-garnet')

  yield api.checkout.test(
      'tryjob_with_patchfile',
      properties=dict(project='garnet',),
      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',
      status='infra_failure',
      properties=dict(project='garnet',),
      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',
      status='infra_failure',
      properties=dict(project='garnet',),
      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',),
      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',),
      patchfile=[{
          'ref': 'refs/changes/cc/aabbcc/1',
          'host': 'https://fuchsia-review.googlesource.com',
          'project': 'topaz',
          # TODO(tonglisayhi): Figure out a way to inject this step_data with
          # whatever nesting this step is
      }]) + api.step_data('checkout.jiri project', api.json.output([]))

  yield api.checkout.test(
      'from_snapshot_tryjob',
      properties=dict(
          project='garnet',
          use_snapshot=True,
          attributes=['attr1', 'attr2'],
      ),
      paths=[api.path['cleanup'].join('snapshot_repo', 'cherrypick.json')],
  ) + api.jiri.read_manifest_element(
      api=api,
      manifest=api.path['cleanup'].join('snapshot_repo', 'snapshot'),
      element_type='project',
      element_name='topaz',
      test_output={'path': 'topaz'},
      nesting='checkout')

  yield api.checkout.test(
      'from_snapshot_dot_path',
      properties=dict(
          project='garnet',
          use_snapshot=True,
      ),
      paths=[api.path['cleanup'].join('snapshot_repo', 'cherrypick.json')],
  ) + api.jiri.read_manifest_element(
      api=api,
      manifest=api.path['cleanup'].join('snapshot_repo', 'snapshot'),
      element_type='project',
      element_name='topaz',
      test_output={'path': '.'},
      nesting='checkout')

  yield api.checkout.test(
      'from_snapshot_not_tryjob',
      tryjob=False,
      properties=dict(
          project='garnet',
          use_snapshot=True,
          attributes=['attr1', 'attr2'],
      ),
      paths=[api.path['cleanup'].join('snapshot_repo', 'cherrypick.json')],
  ) + api.jiri.read_manifest_element(
      api=api,
      manifest=api.path['cleanup'].join('snapshot_repo', 'snapshot'),
      element_type='project',
      element_name='topaz',
      test_output={'path': 'topaz'},
      nesting='checkout')

  yield api.checkout.test(
      'sso_manifest_remote',
      properties=dict(
          remote='sso://manifest-host/manifest')) + api.buildbucket.ci_build(
              git_repo='https://fuchsia.googlesource.com/not-garnet')

  yield api.checkout.test(
      'subbuild_from_spec',
      properties={
          'spec_msg':
              json_format.MessageToJson(
                  Fuchsia(
                      checkout=Fuchsia.Checkout(
                          project='integration',
                          manifest='minimal',
                          remote='https://fuchsia.googlesource.com/manifest',
                      ))),
      })

  yield api.checkout.test(
      'with_cipd_parallelism', properties={'experimental.cipd_max_threads': 0})
