# Copyright 2019 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 gomatools binaries."""

from recipe_engine.recipe_api import Property

import os.path

DEPS = [
    'fuchsia/git',
    'fuchsia/go',
    'fuchsia/upload',
    'recipe_engine/buildbucket',
    'recipe_engine/context',
    'recipe_engine/file',
    'recipe_engine/path',
    'recipe_engine/platform',
    'recipe_engine/properties',
    'recipe_engine/raw_io',
    'recipe_engine/step',
]

PROPERTIES = {
    'package_prefix':
        Property(
            kind=str,
            help='cipd path prefix of goma_tools packages',
            default='fuchsia_internal/third_party/goma/server'),
    'repository':
        Property(
            kind=str,
            help='git repository of goma server',
            default='https://chromium.googlesource.com/infra/goma/server'),
    'source_root':
        Property(
            kind=str,
            help='directory name for goma server code',
            default='go.chromium.org/goma/server'),
    'revision':
        Property(
            kind=str,
            help='git revision/branch of goma server repository',
            default='master'),
    'dry_run':
        Property(
            kind=bool,
            help='Whether to upload gomatools to CIPD.',
            default=True),
}


def RunSteps(api, package_prefix, source_root, repository, revision, dry_run):
  go_path_dir = api.path['cleanup'].join('gopath')
  goma_server_dir = go_path_dir.join('src').join(*(source_root.split('/')))
  api.go('version')
  # Checkout Goma source
  git_revision = api.git.checkout(
      url=repository, path=goma_server_dir, ref=revision)
  # Build goma server
  # TODO: Abstract building go tool logic into a fuchsia recipe module.
  with api.step.nest('build gomatools'):
    for item in api.file.listdir(
        name='list gomatools binaries',
        source=goma_server_dir.join('cmd'),
        test_data=['auth_server', 'setup_cmd']):
      binary_name = os.path.basename(str(item))
      with api.context(
          cwd=goma_server_dir,
          env={
              'GO111MODULE': 'on',
              'GOOS': 'linux',
              'GOARCH': 'amd64',
              'GOPATH': str(go_path_dir),
              'GOCACHE': str(go_path_dir.join('.cache', 'go-build'))
          }):
        api.go(
            'install',
            os.path.join(source_root, 'cmd', binary_name),
            name='build ' + binary_name)
  # Upload
  pkg_dir = go_path_dir.join('bin')
  if not dry_run:
    api.upload.cipd_package(package_prefix + '/gomatools/linux-amd64', pkg_dir,
                            [api.upload.DirectoryPath(pkg_dir)],
                            {'git_revision': git_revision}, repository)


def GenTests(api):
  default_properties = api.properties(
      package_prefix='fuchsia_internal/third_party/goma/server',
      repository='https://chromium.googlesource.com/infra/goma/server',
      source_root='go.chromium.org/goma/server',
      version='master',
      dry_run=True)
  dry_run_off_properties = api.properties(
      package_prefix='fuchsia_internal/third_party/goma/server',
      repository='https://chromium.googlesource.com/infra/goma/server',
      source_root='go.chromium.org/goma/server',
      version='master',
      dry_run=False)

  yield api.test('default') + default_properties + api.buildbucket.try_build(
      git_repo='https://fuchsia.googlesource.com/integration')

  yield api.test(
      'dry run off') + dry_run_off_properties + api.buildbucket.try_build(
          git_repo='https://fuchsia.googlesource.com/integration')
