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