# 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 publishing CIPD prebuilts"""

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

DEPS = [
    'fuchsia/build',
    'fuchsia/buildbucket_util',
    'fuchsia/checkout',
    'fuchsia/fuchsia',
    'fuchsia/jiri',
    'fuchsia/upload',
    'recipe_engine/buildbucket',
    'recipe_engine/cipd',
    'recipe_engine/context',
    'recipe_engine/json',
    'recipe_engine/path',
    'recipe_engine/properties',
    'recipe_engine/step',
]

TARGETS = ['arm64', 'x64']

PROPERTIES = {
    'cipd_pkg_prefix':
        Property(
            kind=str,
            help='The CIPD prefix where the tool binaries should be uploaded',
            default=None),
    'cipd_pkg_name':
        Property(
            kind=str,
            help='The exact CIPD path where the tool binaries should be uploaded (overrides cipd_pkg_prefix)',
            default=None),
    'manifest':
        Property(kind=str, help='Jiri manifest to use'),
    'ninja_targets':
        Property(
            kind=List(basestring),
            help='Extra target args to pass to ninja',
            default=[]),
    'packages':
        Property(kind=List(basestring), help='Packages to build', default=[]),
    'product':
        Property(kind=str, help='Product to build', default=None),
    'board':
        Property(kind=str, help='Board to build', default=None),
    'target':
        Property(kind=Enum(*TARGETS), help='Target to build'),
    'project':
        Property(kind=str, help='Jiri remote manifest project', default=None),
    'remote':
        Property(kind=str, help='Remote manifest repository'),
}


def get_bin_path_components(api, build_dir, ninja_target):
  """Returns a binary's path based on its ninja target.

  Args:
    api: The RecipeApi object
    build_dir: The Fuchsia build output directory
    ninja_target: A specific Ninja target that was built

  Returns:
    bin_dir: The absolute path to the parent directory of bin_name.
    bin_name: The name of the tool binary
  """
  if ninja_target.endswith('/'):
    # This shouldn't happen and would be considered an user error
    # Just in case, sanitize ninja_target for api.path.split()
    # to prevent returning empty string as target_name
    ninja_target = ninja_target[:-1]

  # ninja_target can be expressed in two formats
  #   1) path to binary (e.g. "tools/json_validator")
  #   2) path to ninja target (e.g. "tools:validator.zip")
  # The following logic supports both of these formats
  target_dir, target_name = api.path.split(ninja_target)
  bin_dir = build_dir if ':' in ninja_target else build_dir.join(target_dir)
  bin_name = target_name.split(':')[-1]
  return bin_dir, bin_name


def RunSteps(api, cipd_pkg_prefix, cipd_pkg_name, manifest, target,
             ninja_targets, packages, product, board, project, remote):

  with api.context(infra_steps=True):
    assert manifest
    assert remote
    build = api.buildbucket.build
    checkout = api.checkout.fuchsia_with_options(
        path=api.path['start_dir'],
        manifest=manifest,
        remote=remote,
        project=project,
        build=build)

    revision = str(build.input.gitiles_commit.id)
    assert revision

  build = api.build.with_options(
      build_dir=api.path['start_dir'].join('out'),
      checkout=checkout,
      target=target,
      build_type='release',
      packages=packages,
      board=board,
      product=product,
      ninja_targets=ninja_targets,
      build_images=False,
  )

  if not api.buildbucket_util.is_tryjob:
    platform = '${platform}'
    for ninja_target in ninja_targets:
      bin_dir, bin_name = get_bin_path_components(api, build.fuchsia_build_dir,
                                                  ninja_target)
      api.upload.cipd_package(
          cipd_pkg_name or '%s/%s/%s' % (cipd_pkg_prefix, bin_name, platform),
          bin_dir, [api.upload.FilePath(bin_dir.join(bin_name))],
          {'git_revision': revision},
          repository=remote,
          install_mode=None)


def GenTests(api):
  revision = api.jiri.example_revision
  ci_build = api.buildbucket.ci_build(
      git_repo='https://fuchsia.googlesource.com/build',
      revision=revision,
  )

  yield api.test('default') + ci_build + api.properties(
      cipd_pkg_prefix='fuchsia/tools',
      manifest='manifest/build',
      ninja_targets=['tools/json_validator'],
      target='x64',
      packages=['//build/packages:json_validator'],
      project='build',
      remote='https://fuchsia.googlesource.com/build',
  ) + api.step_data(
      # Mock api.cipd.search(cipd_pkg_name, 'git_revision:' + revision)
      # by expanding the internal step name and providing a result for the step
      'cipd.cipd search fuchsia/tools/json_validator/${platform} git_revision:%s'
      % revision,
      api.json.output({'result': []}),
  )
  yield api.test(
      'gn_target_with_trailing_fwd_slash'
  ) + ci_build + api.properties(
      cipd_pkg_prefix='fuchsia/tools',
      manifest='manifest/build',
      ninja_targets=['tools/json_validator/'],
      target='x64',
      packages=['//build/packages:json_validator'],
      project='build',
      remote='https://fuchsia.googlesource.com/build',
  ) + api.step_data(
      # Mock api.cipd.search(cipd_pkg_name, 'git_revision:' + revision)
      # by expanding the internal step name and providing a result for the step
      'cipd.cipd search fuchsia/tools/json_validator/${platform} git_revision:%s'
      % revision,
      api.json.output({'result': []}),
  )
  yield api.test('cipd_has_revision') + ci_build + api.properties(
      cipd_pkg_prefix='fuchsia/tools',
      manifest='manifest/build',
      ninja_targets=['tools/json_validator'],
      target='x64',
      packages=['//build/packages:json_validator'],
      project='build',
      remote='https://fuchsia.googlesource.com/build',
  ) + api.step_data(
      'cipd.cipd search fuchsia/tools/json_validator/${platform} git_revision:%s'
      % revision,
      api.cipd.example_search(
          'fuchsia/tools/json_validator/${platform}:%s' % revision),
  )
  yield api.test('no_revision') + ci_build + api.properties(
      cipd_pkg_prefix='fuchsia/tools',
      manifest='manifest/build',
      ninja_targets=['tools/json_validator'],
      target='x64',
      packages=['//build/packages:json_validator'],
      project='build',
      remote='https://fuchsia.googlesource.com/build',
  )
