# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed under the Apache License, Version 2.0
# that can be found in the LICENSE file.
"""Recipe for building Ninja."""

from PB.go.chromium.org.luci.common.proto.srcman.manifest import Manifest

from google.protobuf import json_format

DEPS = [
    'fuchsia/git',
    'fuchsia/macos_sdk',
    'fuchsia/upload',
    'recipe_engine/buildbucket',
    'recipe_engine/cipd',
    'recipe_engine/context',
    'recipe_engine/file',
    'recipe_engine/path',
    'recipe_engine/platform',
    'recipe_engine/python',
    'recipe_engine/raw_io',
    'recipe_engine/source_manifest',
    'recipe_engine/step',
]

GIT_URL = 'fuchsia.googlesource.com/third_party/github.com/ninja-build/ninja'
CIPD_SERVER_HOST = 'chrome-infra-packages.appspot.com'


def RunSteps(api):
  manifest = Manifest()

  with api.step.nest('checkout sources'), api.context(infra_steps=True):
    gitiles_commit = api.buildbucket.build_input.gitiles_commit
    repository = ('https://%s/%s' %
                  (gitiles_commit.host, gitiles_commit.project) if
                  gitiles_commit.host and gitiles_commit.project else GIT_URL)
    ref = gitiles_commit.id or 'refs/heads/master'

    src_dir = api.path['start_dir'].join('ninja')
    revision = api.git.checkout(repository, path=src_dir, ref=ref)
    git_checkout = manifest.directories[str(src_dir)].git_checkout
    git_checkout.repo_url = repository
    git_checkout.revision = revision

  with api.step.nest('ensure packages'), api.context(infra_steps=True):
    cipd_dir = api.path['start_dir'].join('cipd')
    pkgs = api.cipd.EnsureFile()
    if api.platform.arch == 'arm' and api.platform.bits == 64:  # pragma: no cover
      pkgs.add_package('fuchsia/clang/${platform}', 'goma')
    else:
      if api.platform.is_linux or api.platform.is_mac:
        pkgs.add_package('fuchsia/third_party/clang/${platform}', 'goma')
    if api.platform.is_linux:
      pkgs.add_package('fuchsia/sysroot/${platform}',
                       'git_revision:a28dfa20af063e5ca00634024c85732e20220419',
                       'sysroot')
    ensured = api.cipd.ensure(cipd_dir, pkgs)
    for subdir, pins in ensured.iteritems():
      directory = manifest.directories[str(cipd_dir.join(subdir))]
      directory.cipd_server_host = CIPD_SERVER_HOST
      for pin in pins:
        directory.cipd_package[pin.package].instance_id = pin.instance_id

  json_manifest = json_format.MessageToJson(
      manifest, preserving_proto_field_name=True)
  api.file.write_text('source manifest', src_dir.join('source_manifest.json'),
                      json_manifest)
  api.source_manifest.set_json_manifest('checkout', json_manifest)

  with api.macos_sdk():
    lto = '-flto' if api.buildbucket.builder_id.bucket == 'prod' else ''
    if api.platform.is_linux:
      sysroot = '--sysroot=%s' % cipd_dir.join('sysroot')
      env = {
          'CXX': cipd_dir.join('bin', 'clang++'),
          'AR': cipd_dir.join('bin', 'llvm-ar'),
          'CXXFLAGS': ' '.join((sysroot, lto)),
          'LDFLAGS': ' '.join((sysroot, lto)),
      }
    elif api.platform.is_mac:
      sysroot = '--sysroot=%s' % 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')).stdout.strip()
      stdlib = '-nostdlib++ %s' % (cipd_dir.join('lib', 'libc++.a'))
      env = {
          'CXX': cipd_dir.join('bin', 'clang++'),
          'AR': cipd_dir.join('bin', 'llvm-ar'),
          'CFLAGS': ' '.join((sysroot, lto)),
          'LDFLAGS': ' '.join((sysroot, '-nostdlib++', stdlib, lto)),
      }
    else:
      env = {}

    with api.context(env=env, cwd=src_dir):
      api.python(
          'bootstrap', src_dir.join('configure.py'), args=['--bootstrap'])

      with api.step.nest('test'):
        api.step('ninja', [src_dir.join('ninja'), 'ninja_test'])
        api.step('test', [src_dir.join('ninja_test')])

      if api.platform.is_linux:
        api.step('strip', [
            cipd_dir.join('bin', 'llvm-objcopy'), '--strip-sections',
            src_dir.join('ninja')
        ])
      elif api.platform.is_mac:
        api.step('strip', ['xcrun', 'strip', '-x', src_dir.join('ninja')])

  ninja = src_dir.join('ninja' + ('.exe' if api.platform.is_win else ''))
  step_result = api.step(
      'ninja version', [ninja, '--version'],
      stdout=api.raw_io.output(),
      step_test_data=lambda: api.raw_io.test_api.stream_output('1.9.0.git'))
  ninja_version = step_result.stdout.strip()

  # Upload the installation to isolate.
  api.upload.upload_isolated(src_dir, [api.upload.FilePath(ninja)])

  if api.buildbucket.builder_id.bucket == 'prod':
    # Upload the installation to CIPD for production builds.
    api.upload.cipd_package(
        'fuchsia/third_party/ninja/${platform}',
        src_dir, [api.upload.FilePath(ninja)], {'git_revision': revision},
        repository=repository,
        extra_tags={'version': ninja_version})


def GenTests(api):
  for platform in ('linux', 'mac', 'win'):
    yield (api.test(platform) + api.platform.name(platform) +
           api.buildbucket.ci_build(
               project='fuchsia',
               bucket='prod',
               git_repo=GIT_URL,
               revision='a' * 40,
           ))
