# Copyright 2017 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 Rust toolchain."""

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

import re

DEPS = [
    'fuchsia/git',
    'fuchsia/gitiles',
    'fuchsia/goma',
    'fuchsia/jiri',
    'fuchsia/macos_sdk',
    'fuchsia/upload',
    'recipe_engine/cipd',
    'recipe_engine/context',
    'recipe_engine/isolated',
    'recipe_engine/json',
    'recipe_engine/path',
    'recipe_engine/platform',
    'recipe_engine/properties',
    'recipe_engine/python',
    'recipe_engine/raw_io',
    'recipe_engine/file',
    'recipe_engine/step',
    'recipe_engine/url',
]

PLATFORM_TO_TRIPLE = {
    'linux-amd64': 'x86_64-unknown-linux-gnu',
    'linux-arm64': 'aarch64-unknown-linux-gnu',
    'mac-amd64': 'x86_64-apple-darwin',
}
PLATFORMS = PLATFORM_TO_TRIPLE.keys()

PACKAGES = ['rust', 'rust_extra_tools']

PROPERTIES = {
    'repository':
        Property(
            kind=str,
            help='Git repository URL',
            default='https://fuchsia.googlesource.com/third_party/rust'),
    'branch':
        Property(kind=str, help='Git branch', default='refs/heads/master'),
    'revision':
        Property(kind=str, help='Revision', default=None),
    'package':
        Property(
            kind=Enum(*PACKAGES), help='Which package to build',
            default='rust'),
}


def RunSteps(api, repository, branch, revision, package):
  api.goma.ensure()

  if not revision:
    revision = api.gitiles.refs(repository).get(branch, None)

  # 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])

  with api.step.nest('ensure_packages'):
    with api.context(infra_steps=True):
      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('infra/swig/${platform}', 'version:3.0.12')
      pkgs.add_package('fuchsia/third_party/clang/${platform}', 'goma')
      pkgs.add_package('fuchsia/sysroot/linux-amd64', 'latest', 'linux-amd64')
      pkgs.add_package('fuchsia/sysroot/linux-arm64', 'latest', 'linux-arm64')
      pkgs.add_package('fuchsia/sdk/core/${platform}', 'latest', 'sdk')
      cipd_dir = api.path['start_dir'].join('cipd')
      api.cipd.ensure(cipd_dir, pkgs)
      sdk_dir = cipd_dir.join('sdk')

  with api.context(infra_steps=True):
    rust_dir = api.path['start_dir'].join('rust')
    api.git.checkout(repository, rust_dir, ref=revision, recursive=True)

  # build rust
  staging_dir = api.path.mkdtemp('rust')
  build_dir = staging_dir.join('build')
  api.file.ensure_directory('build', build_dir)
  pkg_dir = staging_dir.join('rust')
  api.file.ensure_directory('create pkg_dir', pkg_dir)

  with api.macos_sdk(), api.goma.build_with_goma():
    host_triple = PLATFORM_TO_TRIPLE[host_platform]
    if api.platform.name == 'linux':
      host_sysroot = cipd_dir.join(host_platform)
    elif api.platform.name == 'mac':
      # TODO(IN-148): Eventually use our own hermetic sysroot as for Linux.
      step_result = api.step(
          'xcrun', ['xcrun', '--show-sdk-path'],
          stdout=api.raw_io.output(name='sdk-path', add_output_log=True),
          step_test_data=lambda: api.raw_io.test_api.stream_output(
              '/some/xcode/path'))
      host_sysroot = step_result.stdout.strip()
    else:  # pragma: no cover
      assert False, 'unsupported platform'

    targets = [
        'x86_64-unknown-linux-gnu',
        'aarch64-unknown-linux-gnu',
    ]
    if api.platform.is_mac:
      targets.append('x86_64-apple-darwin')

    config_file = 'config.toml'
    api.python(
        'generate config.toml',
        api.resource('generate_config.py'),
        args=[
            '--targets',
            ','.join(targets),
            '--clang-prefix',
            cipd_dir,
            'config_toml',
            '--prefix',
            pkg_dir,
            '--host-sysroot',
            host_sysroot,
            '--goma-dir',
            api.goma.goma_dir,
        ] + (['--extra-tools-only'] if package == 'rust_extra_tools' else []),
        stdout=api.raw_io.output(leak_to=build_dir.join(config_file)))

    env_data = api.python(
        'generate environment',
        api.resource('generate_config.py'),
        args=[
            '--targets',
            ','.join(targets),
            '--clang-prefix',
            cipd_dir,
            'environment',
            '--sdk-dir',
            sdk_dir,
            '--revision',
            revision,
            # TODO(tmandry): Switch to multiarch so these don't need to be separate
            '--linux-amd64-sysroot',
            cipd_dir.join('linux-amd64'),
            '--linux-arm64-sysroot',
            cipd_dir.join('linux-arm64'),
        ] + (['--darwin-sysroot', host_sysroot] if api.platform.is_mac else []),
        stdout=api.raw_io.output(name='environment', add_output_log=True),
        step_test_data=lambda: api.raw_io.test_api.stream_output(
            'RUST_BACKTRACE=1'))
    env = {}
    for line in env_data.stdout.splitlines():
      key, value = line.split('=', 1)
      env[key] = value

    env_prefixes = {'PATH': [cipd_dir, cipd_dir.join('bin')]}
    with api.context(cwd=build_dir, env=env, env_prefixes=env_prefixes):
      api.python(
          'rust install',
          rust_dir.join('x.py'),
          args=['install', '--config', config_file])

  api.upload.upload_isolated(pkg_dir)

  # package rust
  step_result = api.step(
      'rust version', [pkg_dir.join('bin', 'rustc'), '--version'],
      stdout=api.raw_io.output(),
      step_test_data=lambda: api.raw_io.test_api.stream_output(
          'rustc 1.19.0-nightly (75b056812 2017-05-15)'))
  m = re.search(r'rustc ([0-9a-z.-]+)', step_result.stdout)
  assert m, 'Cannot determine Rust version'
  version = m.group(1)

  api.upload.cipd_package(
      'fuchsia/%s/${platform}' % package,
      pkg_dir, [api.upload.DirectoryPath(pkg_dir)], {'git_revision': revision},
      repository=repository,
      extra_tags={'version': version})


def GenTests(api):
  revision = '75b05681239cb309a23fcb4f8864f177e5aa62da'
  for platform in ('linux', 'mac'):
    for package in ('rust', 'rust_extra_tools'):
      yield (api.test('%s_%s' % (package, platform)) +
             api.platform.name(platform) + api.properties(package=package) +
             api.gitiles.refs('refs', ('refs/heads/master', revision)))
      yield (api.test('%s_%s_new' % (package, platform)) +
             api.platform.name(platform) + api.properties(package=package) +
             api.gitiles.refs('refs', ('refs/heads/master', revision)) +
             api.step_data(
                 'cipd.cipd search fuchsia/%s/${platform} ' % package +
                 'git_revision:' + revision, api.json.output({'result': []})))
