# 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 and running LLVM test-suite."""

from recipe_engine.config import ConfigGroup, Enum, Single
from recipe_engine.recipe_api import Property

DEPS = [
    'fuchsia/git',
    'recipe_engine/buildbucket',
    'recipe_engine/cipd',
    'recipe_engine/context',
    'recipe_engine/file',
    'recipe_engine/isolated',
    'recipe_engine/json',
    'recipe_engine/path',
    'recipe_engine/platform',
    'recipe_engine/properties',
    'recipe_engine/python',
    'recipe_engine/step',
]

PROPERTIES = {
    'repository':
        Property(
            kind=str,
            help='Git repository URL',
            default='https://fuchsia.googlesource.com/third_party/llvm-test-suite'
        ),
    'platform':
        Property(kind=str, help='CIPD platform for the target', default=None),
    'clang_toolchain':
        Property(
            kind=ConfigGroup(
                type=Enum('cipd', 'isolated'), instance=Single(str)),
            help='clang toolchain used to build the test-suite',
            default={}),
}


def RunSteps(api, repository, platform, clang_toolchain):
  build_input = api.buildbucket.build_input
  revision = build_input.gitiles_commit.id
  if build_input.gitiles_commit.host and build_input.gitiles_commit.project:
    repository = 'https://%s/%s' % (build_input.gitiles_commit.host,
                                    build_input.gitiles_commit.project)

  # TODO: factor this out into a host_build recipe module.
  host_platform = '%s-%s' % (api.platform.name.replace('win', 'windows'), {
      'intel': {
          32: '386',
          64: 'amd64',
      },
      'arm': {
          32: 'armv6',
          64: 'arm64',
      },
  }[api.platform.arch][api.platform.bits])
  target_platform = platform or host_platform

  with api.step.nest('cipd_packages'), api.context(infra_steps=True):
    cipd_dir = api.path['start_dir'].join('cipd')
    pkgs = api.cipd.EnsureFile()
    pkgs.add_package('infra/cmake/${platform}', 'version:3.9.2')
    pkgs.add_package('infra/ninja/${platform}', 'version:1.8.2')
    pkgs.add_package('fuchsia/third_party/clang/${platform}', 'goma')
    pkgs.add_package('fuchsia/sysroot/' + target_platform, 'latest',
                     target_platform)
    api.cipd.ensure(cipd_dir, pkgs)

  # Get the toolchain.
  with api.step.nest('toolchain'), api.context(infra_steps=True):
    clang_instance = clang_toolchain['instance']
    clang_dir = api.path.mkdtemp('clang')

    if clang_toolchain['type'] == 'cipd':
      pkgs = api.cipd.EnsureFile()
      pkgs.add_package('fuchsia/third_party/clang/${platform}', clang_instance)
      api.cipd.ensure(clang_dir, pkgs)
    elif clang_toolchain['type'] == 'isolated':
      api.isolated.download(
          'download', isolated_hash=clang_instance, output_dir=clang_dir)
    else:  # pragma: no cover
      assert False, 'unsupported clang_toolchain package type'

  # Get sources for test-suite.
  with api.step.nest('git'), api.context(infra_steps=True):
    test_suite_dir = api.path['start_dir'].join('llvm-test-suite')
    revision = api.git.checkout(repository, test_suite_dir, ref=revision)

  build_dir = api.path['start_dir'].join('test-suite-build')
  api.file.ensure_directory('create test-suite-build dir', build_dir)

  with api.step.nest('test-suite'), api.context(cwd=build_dir):
    api.step('configure', [
        cipd_dir.join('bin', 'cmake'),
        '-GNinja',
        '-DCMAKE_MAKE_PROGRAM=%s' % cipd_dir.join('ninja'),
        '-DCMAKE_C_COMPILER=%s' % clang_dir.join('bin', 'clang'),
        '-DCMAKE_CXX_COMPILER=%s' % clang_dir.join('bin', 'clang++'),
        '-DCMAKE_EXE_LINKER_FLAGS=-ldl -lpthread',
        '-DCMAKE_SHARED_LINKER_FLAGS=-ldl -lpthread',
        '-DCMAKE_SYSROOT=%s' % cipd_dir.join(target_platform),
        '-DTEST_SUITE_CXX_ABI=libc++',
        '-C',
        test_suite_dir.join('cmake', 'caches', 'O3.cmake'),
        test_suite_dir,
    ])
    api.step('build', [cipd_dir.join('ninja')])
    api.python(
        'test',
        script=api.resource('llvm-lit.py'),
        args=[
            '-o',
            api.json.output(leak_to=build_dir.join('results.json')),
            build_dir,
        ])

  # TODO(BLD-332): upload results.json to catapult


def GenTests(api):
  yield (api.test('cipd') + api.buildbucket.ci_build(
      project='fuchsia',
      bucket='ci',
      git_repo='https://fuchsia.googlesource.com/third_party/llvm-test-suite',
      revision='a' * 40,
  ) + api.platform.name('linux') + api.properties(clang_toolchain={
      'type': 'cipd',
      'instance': api.cipd.make_resolved_version(None),
  }))
  yield (api.test('isolate') + api.buildbucket.ci_build(
      project='fuchsia',
      bucket='ci',
      git_repo='https://fuchsia.googlesource.com/third_party/llvm-test-suite',
      revision='a' * 40,
  ) + api.platform.name('linux') + api.properties(clang_toolchain={
      'type': 'isolated',
      'instance': 'abc123',
  }))
