# 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.
"""Recipe for testing LUCI configs."""

import difflib
from recipe_engine.recipe_api import Property

DEPS = [
    'fuchsia/checkout',
    'fuchsia/jiri',
    'recipe_engine/buildbucket',
    'recipe_engine/context',
    'recipe_engine/file',
    'recipe_engine/path',
    'recipe_engine/properties',
    'recipe_engine/raw_io',
    'recipe_engine/step',
]

PROPERTIES = {
    'config_project':
        Property(
            kind=str,
            help='Jiri remote manifest project containing the luci configs'),
    'manifest':
        Property(kind=str, help='Jiri manifest to use'),
    'remote':
        Property(kind=str, help='Remote manifest repository'),
    'starlark_paths':
        Property(
            kind=list, help='Starlark file paths to validate', default=None),
}

_PREBUILT_PROJECT_REMOTE = 'https://fuchsia.googlesource.com/infra/prebuilt'


def RunSteps(api, config_project, manifest, remote, starlark_paths):
  if not starlark_paths:
    raise api.step.InfraFailure('starlark_paths must be set')

  with api.context(infra_steps=True):
    api.checkout.with_options(
        path=api.path['start_dir'],
        manifest=manifest,
        remote=remote,
        project=config_project,
        build_input=api.buildbucket.build.input,
    )

  # Find the required jiri projects.
  config_jiri_project, prebuilt_jiri_project = None, None
  jiri_projects = api.jiri.project()
  for jiri_project in jiri_projects.json.output:
    if jiri_project['name'] == config_project:
      config_jiri_project = jiri_project
    if jiri_project['remote'] == _PREBUILT_PROJECT_REMOTE:
      prebuilt_jiri_project = jiri_project
  assert config_jiri_project, 'Failed to find project %s' % config_project
  assert prebuilt_jiri_project, ('Failed to find project with remote %s' %
                                 _PREBUILT_PROJECT_REMOTE)

  # Needs to be kept in sync with //infra/prebuilt/tools/cipd.ensure.
  lucicfg_path = api.path['start_dir'].join(prebuilt_jiri_project['path'],
                                            'tools', 'lucicfg')

  with api.step.nest('validate'):
    for relative_path in starlark_paths:
      abs_path = api.path['start_dir'].join(config_jiri_project['path'],
                                            relative_path)
      api.step(relative_path,
               [lucicfg_path, 'validate', '-fail-on-warnings', abs_path])


def GenTests(api):
  properties_dict = {
      'config_project': 'fuchsia-infra/config',
      'manifest': 'manifest/infra',
      'remote': 'https://fuchsia.googlesource.com/manifest',
      'starlark_paths': ['main.star', 'dev.star'],
  }
  properties = api.properties(**properties_dict)
  jiri_projects = api.step_data(
      'jiri project',
      api.jiri.project([{
          'name': 'fuchsia-infra/config',
          'path': 'config',
          'remote': 'https://fuchsia.googlesource.com/infra/config'
      }, {
          'name': 'prebuilt',
          'path': 'fuchsia-infra/prebuilt',
          'remote': 'https://fuchsia.googlesource.com/infra/prebuilt'
      }]))

  yield (api.test('starlark') + properties + jiri_projects)

  del properties_dict['starlark_paths']
  properties = api.properties(**properties_dict)
  yield (api.test('starlark_paths_not_set') + properties)
