# 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 building and testing cobalt-registry.

Uses Cobalt's cobaltb.py script to build the config_parser tool,
then runs it on Cobalt's `config` repo.
"""

from recipe_engine.recipe_api import Property

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

PROPERTIES = {
    'remote':
        Property(kind=str, help='URL to remote repo containing Jira manifest'),
    'manifest':
        Property(
            kind=str, help='Jiri manifest file to use, relative to `remote`'),
    'project':
        Property(
            kind=str,
            help='Jiri manifest project name for the cobalt-registry repo.',
            default='cobalt-registry'),
}


def RunSteps(api, remote, manifest, project):
  # Check out the project from the specified manifest.
  with api.context(infra_steps=True):
    build_input = api.buildbucket.build.input
    api.checkout.with_options(
        path=api.path['start_dir'],
        manifest=manifest,
        remote=remote,
        project=project,
        patch_project=project,
        build_input=build_input,
    )

    revision = build_input.gitiles_commit.id
    cobalt_config_project = api.jiri.project([project]).json.output[0]
    if not revision:
      revision = cobalt_config_project['revision']
      api.step.active_result.presentation.properties['got_revision'] = revision

  # Root of the cobalt repo as checked out by the manifest.
  cobalt_src_dir = api.path['start_dir'].join('third_party/cobalt')
  tools_dir = api.path['start_dir'].join('tools')

  # Build config_parser.
  with api.context(cwd=cobalt_src_dir):
    api.python('setup', './cobaltb.py', args=['setup'])
    api.python('build', './cobaltb.py', args=['build', '--out_dir', tools_dir])

  config_parser_bin = tools_dir.join('config_parser')
  config_validator_bin = tools_dir.join('config_change_validator')

  # Root of the config repo as checked out by the manifest.
  config_src_dir = api.path['start_dir'].join(cobalt_config_project['path'])

  # Run config_parser on the config repo checkout.
  api.step('check config', [
      config_parser_bin,
      '--output_file',
      api.path['start_dir'].join('new_config'),
      '--config_dir',
      config_src_dir,
      '--allow_empty_output',
  ])

  with api.context(cwd=config_src_dir):
    api.step('checkout parent', ['git', 'checkout', 'HEAD^'])

  api.step('check parent config', [
      config_parser_bin,
      '--output_file',
      api.path['start_dir'].join('old_config'),
      '--config_dir',
      config_src_dir,
      '--allow_empty_output',
  ])

  commit_msg = ""
  with api.context(cwd=config_src_dir):
    api.step('checkout head', ['git', 'checkout', '-'])
    commit_msg = api.step(
        'read commit message', ['git', 'show', '-s', '--format=%b'],
        stdout=api.raw_io.output()).stdout

  api.step('validate change', [
      config_validator_bin,
      '--old_config',
      api.path['start_dir'].join('old_config'),
      '--new_config',
      api.path['start_dir'].join('new_config'),
      '--commit_msg',
      commit_msg,
  ])


def GenTests(api):
  yield (api.test('ci') + api.buildbucket.ci_build(
      git_repo='https://fuchsia.googlesource.com/cobalt-registry',) +
         api.properties(
             remote='https://fuchsia.googlesource.com/manifest',
             manifest='config.manifest',
             project='cobalt-registry',
         ) + api.properties(project='cobalt-registry'))
  yield (api.test('cq_try') + api.buildbucket.try_build(
      git_repo='https://fuchsia.googlesource.com/cobalt-registry',) +
         api.properties.tryserver(
             remote='https://fuchsia.googlesource.com/manifest',
             manifest='config.manifest',
             project='cobalt-registry',
         ) + api.properties(project='cobalt-registry'))
