# Copyright 2018 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 FFmpeg and uploading it and required source files."""

from recipe_engine.recipe_api import Property

DEPS = [
    'fuchsia/build',
    'fuchsia/buildbucket_util',
    'fuchsia/checkout',
    'fuchsia/fuchsia',
    'fuchsia/gsutil',
    'fuchsia/jiri',
    'fuchsia/upload',
    'recipe_engine/buildbucket',
    'recipe_engine/cipd',
    'recipe_engine/context',
    'recipe_engine/file',
    'recipe_engine/path',
    'recipe_engine/properties',
    'recipe_engine/python',
    'recipe_engine/step',
]

# Patterns of source code to include in the archive that this recipe produces.
# All relative to third_party/ffmpeg.
SOURCE_PATTERNS = ['fuchsia/config/**/*', 'lib*/*.h']

TARGETS = ['arm64', 'x64']

VARIANTS = ['lto', 'thinlto', 'profile', 'asan', 'ubsan', 'asan-ubsan']


def RunSteps(api):
  checkout = api.checkout.fuchsia_with_options(
      path=api.path['start_dir'],
      build=api.buildbucket.build,
      manifest='third_party/ffmpeg',
      remote='http://fuchsia.googlesource.com/integration',
  )

  staging_dir = api.path.mkdtemp('ffmpeg')
  pkg_dir = staging_dir.join('root')

  # Build and archive for all targets before uploading any to avoid an
  # incomplete upload.
  for target in TARGETS:
    with api.step.nest(target):
      ninja_targets = ['%s-shared/libffmpeg.so' % target]
      for variant in VARIANTS:
        ninja_targets.append('%s-%s-shared/libffmpeg.so' % (target, variant))
      build_results = api.build.with_options(
          build_dir=api.path['start_dir'].join('out'),
          checkout=checkout,
          target=target,
          build_type='release',
          product='products/core.gni',
          packages=['//third_party/ffmpeg:ffmpeg_variants'],
          ninja_targets=ninja_targets,
          variants=VARIANTS,
          gn_args=['use_prebuilt_ffmpeg=false'],
          build_images=False,
      )
      with api.context(infra_steps=True):
        shared_build_dir = build_results.fuchsia_build_dir.join('%s-shared' %
                                                                target)
        lib_dir = pkg_dir.join('arch', target, 'lib')
        api.file.ensure_directory('create lib dir', lib_dir)
        api.file.copy('copy libffmpeg.so',
                      shared_build_dir.join('libffmpeg.so'), lib_dir)
        debug_dir = pkg_dir.join('arch', target, 'debug')
        api.file.ensure_directory('create debug dir', debug_dir)
        api.file.copy('copy libffmpeg.so (debug)',
                      shared_build_dir.join('lib.unstripped', 'libffmpeg.so'),
                      debug_dir)

        for variant in VARIANTS:
          with api.step.nest(variant):
            shared_variant_build_dir = build_results.fuchsia_build_dir.join(
                '%s-%s-shared' % (target, variant))
            lib_variant_dir = lib_dir.join(variant)
            api.file.ensure_directory('create lib dir', lib_variant_dir)
            api.file.copy('copy libffmpeg.so',
                          shared_variant_build_dir.join('libffmpeg.so'),
                          lib_variant_dir)
            debug_variant_dir = debug_dir.join(variant)
            api.file.ensure_directory('create debug dir', debug_variant_dir)
            api.file.copy(
                'copy libffmpeg.so (debug)',
                shared_variant_build_dir.join('lib.unstripped', 'libffmpeg.so'),
                debug_variant_dir)

  ffmpeg_dir = checkout.root_dir.join('third_party', 'ffmpeg')
  api.python(
      'copy files',
      api.resource('copy_files.py'),
      args=[
          ffmpeg_dir,
          pkg_dir.join('pkg', 'ffmpeg', 'include'),
      ] + SOURCE_PATTERNS)
  docs_dir = pkg_dir.join('pkg', 'ffmpeg', 'docs')
  api.file.ensure_directory('create docs dir', docs_dir)
  api.file.copy('copy license', ffmpeg_dir.join('LICENSE.md'),
                docs_dir.join('LICENSE.md'))

  if api.buildbucket_util.is_tryjob:
    return

  with api.context(infra_steps=True):
    # api.checkout.fuchsia_with_options() will have ensured that jiri exists.
    project = api.jiri.project(['third_party/ffmpeg']).json.output[0]

  api.upload.cipd_package(
      'fuchsia/lib/ffmpeg/fuchsia',
      pkg_dir, [api.upload.DirectoryPath(pkg_dir)],
      {'git_revision': project['revision']},
      repository=project['remote'])


def GenTests(api):
  yield (api.fuchsia.test(
      'default',
      clear_default_properties=True,
      properties=dict(project='third_party/ffmpeg'),
  ) + api.step_data(
      'cipd.cipd search fuchsia/lib/ffmpeg/fuchsia git_revision:' +
      api.jiri.example_revision,
      api.cipd.example_search('fuchsia/lib/ffmpeg/fuchsia', [])))
  yield api.fuchsia.test(
      'ci',
      clear_default_properties=True,
      properties=dict(project='third_party/ffmpeg'),
  )
  yield api.fuchsia.test(
      'cq',
      clear_default_properties=True,
      tryjob=True,
      properties=dict(project='third_party/ffmpeg'),
  )
