# 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/goma',
    '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):
  api.goma.ensure()

  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.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(), api.goma.build_with_goma():
    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,
           ))
