# 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 CMake."""

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

from google.protobuf import json_format

import re

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/raw_io',
    'recipe_engine/source_manifest',
    'recipe_engine/step',
]

GIT_URL = 'https://fuchsia.googlesource.com/third_party/github.com/Kitware/CMake'
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
    url = ('https://%s/%s' % (gitiles_commit.host, gitiles_commit.project)
           if gitiles_commit.host and gitiles_commit.project else GIT_URL)
    ref = gitiles_commit.id

    src_dir = api.path['start_dir'].join('cmake')
    revision = api.git.checkout(url, path=src_dir, ref=ref)
    git_checkout = manifest.directories[str(src_dir)].git_checkout
    git_checkout.repo_url = url
    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()
    pkgs.add_package('fuchsia/third_party/clang/${platform}', 'goma')
    if api.platform.is_linux:
      pkgs.add_package('fuchsia/sysroot/${platform}',
                       'git_revision:a28dfa20af063e5ca00634024c85732e20220419',
                       'sysroot')
    pkgs.add_package('infra/3pp/tools/cmake/${platform}', 'version:3.13.5')
    pkgs.add_package('infra/3pp/tools/ninja/${platform}', 'version:1.9.0')
    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

  staging_dir = api.path.mkdtemp('cmake')
  build_dir = staging_dir.join('cmake_build_dir')
  api.file.ensure_directory('create build dir', build_dir)
  pkg_dir = staging_dir.join('cmake')
  api.file.ensure_directory('create pkg dir', pkg_dir)

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

  with api.macos_sdk(), api.context(cwd=build_dir):
    options = [
        '-GNinja',
        '-DCMAKE_C_COMPILER=%s' % cipd_dir.join('bin', 'clang'),
        '-DCMAKE_CXX_COMPILER=%s' % cipd_dir.join('bin', 'clang++'),
        '-DCMAKE_ASM_COMPILER=%s' % cipd_dir.join('bin', 'clang'),
        '-DCMAKE_MAKE_PROGRAM=%s' % cipd_dir.join('ninja'),
        '-DCMAKE_BUILD_TYPE=Release',
        '-DCMAKE_INSTALL_PREFIX=',
        '-DCMAKE_USE_OPENSSL=OFF',
        '-DCMake_BUILD_LTO=ON',
        # TODO(phosek): build ncurses?
        '-DBUILD_CursesDialog=OFF',
    ]

    if api.platform.is_linux:
      options.extend([
          '-DCMAKE_SYSROOT=%s' % cipd_dir.join('sysroot'),
      ])
    elif api.platform.is_mac:
      options.extend([
          '-DCMAKE_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(),
      ] + [
          '-DCMAKE_%s_LINKER_FLAGS=-nostdlib++ %s' %
          (mode, cipd_dir.join('lib', 'libc++.a'))
          for mode in ['SHARED', 'MODULE', 'EXE']
      ])

    api.step('configure', [
        cipd_dir.join('bin', 'cmake'),
    ] + options + [src_dir])
    api.step('build', [cipd_dir.join('ninja')])
    # TODO: CMake tests are failing, disable them until we figure out why.
    # api.step('test', [cipd_dir.join('ninja'), 'test'])
    with api.context(env={'DESTDIR': pkg_dir}):
      api.step('install', [cipd_dir.join('ninja'), 'install/strip'])

  step_result = api.step(
      'cmake version', [build_dir.join('bin', 'cmake'), '--version'],
      stdout=api.raw_io.output(),
      step_test_data=lambda: api.raw_io.test_api.stream_output(
          'cmake version 3.9.20170826-g6285f-dirty'))
  m = re.search(r'cmake version (\w+)', step_result.stdout)
  assert m, 'Cannot determine CMake version'
  cmake_version = m.group(1)

  # Upload the installation to isolate.
  api.upload.upload_isolated(pkg_dir)

  if api.buildbucket.builder_id.bucket == 'prod':
    # Upload the installation to CIPD for production builds.
    api.upload.cipd_package(
        'fuchsia/third_party/cmake/${platform}',
        pkg_dir, [api.upload.DirectoryPath(pkg_dir)],
        {'git_revision': revision},
        repository=url,
        extra_tags={'version': cmake_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,
           ))
