# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from contextlib import contextmanager

from PB.recipes.flutter.engine.engine import InputProperties
from PB.recipes.flutter.engine.engine import EnvProperties

from PB.go.chromium.org.luci.buildbucket.proto import build as build_pb2
from google.protobuf import struct_pb2

DEPS = [
    'depot_tools/depot_tools',
    'depot_tools/gclient',
    'flutter/bucket_util',
    'flutter/os_utils',
    'flutter/repo_util',
    'flutter/zip',
    'fuchsia/gcloud',
    'fuchsia/goma',
    'recipe_engine/buildbucket',
    'recipe_engine/context',
    'recipe_engine/file',
    'recipe_engine/path',
    'recipe_engine/platform',
    'recipe_engine/properties',
    'recipe_engine/raw_io',
    'recipe_engine/runtime',
    'recipe_engine/step',
]

# Account for ~1 hour queue time when there is a high number of commits.
DRONE_TIMEOUT_SECS = 7200

BUCKET_NAME = 'flutter_infra_release'
MAVEN_BUCKET_NAME = 'download.flutter.io'
ICU_DATA_PATH = 'third_party/icu/flutter/icudtl.dat'
GIT_REPO = (
    'https://flutter.googlesource.com/mirrors/engine')
IMPELLERC_SHADER_LIB_PATH = 'shader_lib'

PROPERTIES = InputProperties
ENV_PROPERTIES = EnvProperties

def MoveShaderLib(api):
  api.file.move(
      'Move the impellerc shader lib to the current directory in preparation for upload',
      GetCheckoutPath(api).join('out', 'linux_debug_arm64',
                                IMPELLERC_SHADER_LIB_PATH), GetCheckoutPath(api).join(IMPELLERC_SHADER_LIB_PATH)
  )

def GetCheckoutPath(api):
  return api.path['cache'].join('builder', 'src')


def GetGitHash(api):
  with api.context(cwd=GetCheckoutPath(api)):
    return api.step(
        "Retrieve git hash", ["git", "rev-parse", "HEAD"],
        stdout=api.raw_io.output_text()).stdout.strip()


def GetCloudPath(api, path):
  git_hash = api.buildbucket.gitiles_commit.id
  if api.runtime.is_experimental:
    return 'flutter/experimental/%s/%s' % (git_hash, path)
  return 'flutter/%s/%s' % (git_hash, path)


def Build(api, config, *targets):
  checkout = GetCheckoutPath(api)
  build_dir = checkout.join('out/%s' % config)
  goma_jobs = api.properties['goma_jobs']
  ninja_args = [api.depot_tools.ninja_path, '-j', goma_jobs, '-C', build_dir]
  ninja_args.extend(targets)
  with api.goma.build_with_goma(), api.depot_tools.on_path():
    name = 'build %s' % ' '.join([config] + list(targets))
    api.step(name, ninja_args)


def RunGN(api, *args):
  checkout = GetCheckoutPath(api)
  gn_cmd = ['python', checkout.join('flutter/tools/gn'), '--goma']
  gn_cmd.extend(args)
  api.step('gn %s' % ' '.join(args), gn_cmd)


def NotifyPubsub(api,
                 buildername,
                 bucket,
                 topic='projects/flutter-dashboard/topics/luci-builds-prod'):
  """Sends a pubsub message to the topic specified with buildername and githash, identifying
  the completed build.

  Args:
    api: luci api object.
    buildername(str): The name of builder.
    bucket(str): The name of the bucket.
    topic(str): (optional) gcloud topic to publish message to.
  """
  githash = GetGitHash(api)
  cmd = [
      'pubsub', 'topics', 'publish', topic,
      '--message={"buildername" : "%s", "bucket" : "%s", "githash" : "%s"}' %
      (buildername, bucket, githash)
  ]
  api.gcloud(*cmd)


def UploadArtifacts(api,
                    platform,
                    file_paths=[],
                    directory_paths=[],
                    archive_name='artifacts.zip',
                    pkg_root=None):
  dir_label = '%s UploadArtifacts %s' % (platform, archive_name)
  with api.os_utils.make_temp_directory(dir_label) as temp_dir:
    local_zip = temp_dir.join('artifacts.zip')
    remote_name = '%s/%s' % (platform, archive_name)
    remote_zip = GetCloudPath(api, remote_name)
    if pkg_root is None:
      pkg_root = GetCheckoutPath(api)
    pkg = api.zip.make_package(pkg_root, local_zip)
    api.bucket_util.add_files(pkg, file_paths)
    api.bucket_util.add_directories(pkg, directory_paths)

    pkg.zip('Zip %s %s' % (platform, archive_name))
    if api.bucket_util.should_upload_packages():
      api.bucket_util.safe_upload(local_zip, remote_zip)


def UploadDartSdk(api, archive_name, target_path='src/out/host_debug'):
  api.bucket_util.upload_folder('Upload Dart SDK', target_path, 'dart-sdk',
                                archive_name)


def PackageLinuxDesktopVariant(api, label, bucket_name):
  artifacts = [
      'libflutter_linux_gtk.so',
  ]
  if bucket_name.endswith('profile') or bucket_name.endswith('release'):
    artifacts.append('gen_snapshot')
  # Headers for the library are in the flutter_linux folder.
  api.bucket_util.upload_folder_and_files(
      'Upload linux-arm64 Flutter GTK artifacts',
      'src/out/%s' % label,
      'flutter_linux',
      'linux-arm64-flutter-gtk.zip',
      platform=bucket_name,
      file_paths=artifacts
  )


def BuildLinux(api):
  RunGN(api, '--runtime-mode', 'debug', '--full-dart-sdk', '--target-os=linux',
        '--linux-cpu=arm64', '--prebuilt-dart-sdk')
  Build(api, 'linux_debug_arm64')

  RunGN(api, '--runtime-mode', 'profile', '--no-lto', '--target-os=linux',
        '--linux-cpu=arm64', '--prebuilt-dart-sdk')
  Build(api, 'linux_profile_arm64')

  RunGN(api, '--runtime-mode', 'release', '--target-os=linux',
        '--linux-cpu=arm64', '--prebuilt-dart-sdk')
  Build(api, 'linux_release_arm64')

  MoveShaderLib(api)

  UploadArtifacts(api, 'linux-arm64', [
      ICU_DATA_PATH,
      'out/linux_debug_arm64/flutter_tester',
      'out/linux_debug_arm64/gen/flutter/impeller/compiler/LICENSE.impellerc.md',
      'out/linux_debug_arm64/gen/flutter/tools/path_ops/LICENSE.path_ops.md',
      'out/linux_debug_arm64/impellerc',
      'out/linux_debug_arm64/libpath_ops.so',
      'out/linux_debug_arm64/libtessellator.so',
      'out/linux_debug_arm64/gen/flutter/lib/snapshot/isolate_snapshot.bin',
      'out/linux_debug_arm64/gen/flutter/lib/snapshot/vm_isolate_snapshot.bin',
      'out/linux_debug_arm64/gen/frontend_server.dart.snapshot',
  ])

  # Font subset
  UploadArtifacts(
      api,
      'linux-arm64', [
          'out/linux_release_arm64/font-subset',
          'out/linux_debug_arm64/gen/const_finder.dart.snapshot',
      ],
      archive_name='font-subset.zip'
  )

  # Desktop embedding.
  PackageLinuxDesktopVariant(api, 'linux_debug_arm64', 'linux-arm64-debug')
  PackageLinuxDesktopVariant(api, 'linux_profile_arm64', 'linux-arm64-profile')
  PackageLinuxDesktopVariant(api, 'linux_release_arm64', 'linux-arm64-release')
  # Legacy; remove once Flutter tooling is updated to use the -debug location.
  PackageLinuxDesktopVariant(api, 'linux_debug_arm64', 'linux-arm64')

  UploadDartSdk(
      api,
      archive_name='dart-sdk-linux-arm64.zip',
      target_path='src/out/linux_debug_arm64')


def RunSteps(api, properties, env_properties):
  # Collect memory/cpu/process before task execution.
  api.os_utils.collect_os_info()

  cache_root = api.path['cache'].join('builder')
  checkout = GetCheckoutPath(api)

  api.file.rmtree('Clobber build output', checkout.join('out'))

  api.file.ensure_directory('Ensure checkout cache', cache_root)
  api.goma.ensure()
  dart_bin = checkout.join('third_party', 'dart', 'tools', 'sdks', 'dart-sdk',
                           'bin')

  android_home = checkout.join('third_party', 'android_tools', 'sdk')

  env = {
    'GOMA_DIR': api.goma.goma_dir,
    'ANDROID_HOME': str(android_home),
    'FLUTTER_PREBUILT_DART_SDK': 'True',
  }
  env_prefixes = {}

  api.repo_util.engine_checkout(cache_root, env, env_prefixes)

  # Delete derived data on mac. This is a noop for other platforms.
  api.os_utils.clean_derived_data()

  # Various scripts we run assume access to depot_tools on path for `ninja`.
  with api.context(
      cwd=cache_root, env=env,
      env_prefixes=env_prefixes), api.depot_tools.on_path():

    api.gclient.runhooks()

    if api.platform.is_linux:
      if api.properties.get('build_host', True):
        BuildLinux(api)

    if api.platform.is_mac:
      # no-op
      raise api.step.StepFailure('Mac Arm host builds not supported yet.')
    if api.platform.is_win:
      raise api.step.StepFailure('Windows Arm host builds not supported yet.')

  # Notifies of build completion
  # TODO(crbug.com/843720): replace this when user defined notifications is implemented.
  try:
    NotifyPubsub(api, api.buildbucket.builder_name,
                 api.buildbucket.build.builder.bucket)
  except (api.step.StepFailure) as e:
    pass

  # This is to clean up leaked processes.
  api.os_utils.kill_processes()
  # Collect memory/cpu/process after task execution.
  api.os_utils.collect_os_info()


# pylint: disable=line-too-long
# See https://chromium.googlesource.com/infra/luci/recipes-py/+/refs/heads/master/doc/user_guide.md
# The tests in here make sure that every line of code is used and does not fail.
# pylint: enable=line-too-long
def GenTests(api):
  git_revision = 'abcd1234'
  for platform in ('mac', 'linux', 'win'):
    for should_upload in (True, False):
      test = api.test(
          '%s%s' % (platform, '_upload' if should_upload else ''),
          api.platform(platform, 64),
          api.buildbucket.ci_build(
              builder='%s Engine' % platform.capitalize(),
              git_repo=GIT_REPO,
              project='flutter',
              revision='%s' % git_revision,
          ),
          api.runtime(is_experimental=False),
          api.properties(
              InputProperties(
                  clobber=False,
                  goma_jobs='1024',
                  fuchsia_ctl_version='version:0.0.2',
                  build_host=True,
                  build_fuchsia=True,
                  build_android_aot=True,
                  build_android_debug=True,
                  upload_packages=should_upload,
                  force_upload=True,
              ),),
          api.properties.environ(
              EnvProperties(SWARMING_TASK_ID='deadbeef')),
      )
      yield test

  for should_upload in (True, False):
    yield api.test(
        'experimental%s' % ('_upload' if should_upload else ''),
        api.buildbucket.ci_build(
            builder='Linux Engine',
            git_repo=GIT_REPO,
            project='flutter',
        ),
        api.runtime(is_experimental=True),
        api.properties(
            InputProperties(
                goma_jobs='1024',
                fuchsia_ctl_version='version:0.0.2',
                android_sdk_license='android_sdk_hash',
                android_sdk_preview_license='android_sdk_preview_hash',
                upload_packages=should_upload,
            )),
    )
  yield api.test(
      'clobber',
      api.buildbucket.ci_build(
          builder='Linux Host Engine',
          git_repo='https://github.com/flutter/engine',
          project='flutter'),
      api.runtime(is_experimental=True),
      api.properties(
          InputProperties(
              clobber=True,
              git_url='https://github.com/flutter/engine',
              goma_jobs='200',
              git_ref='refs/pull/1/head',
              fuchsia_ctl_version='version:0.0.2',
              build_host=True,
              build_fuchsia=True,
              build_android_aot=True,
              build_android_debug=True,
              android_sdk_license='android_sdk_hash',
              android_sdk_preview_license='android_sdk_preview_hash')),
  )
  yield api.test(
      'pull_request',
      api.buildbucket.ci_build(
          builder='Linux Host Engine',
          git_repo='https://github.com/flutter/engine',
          project='flutter'),
      api.runtime(is_experimental=True),
      api.properties(
          InputProperties(
              clobber=False,
              git_url='https://github.com/flutter/engine',
              goma_jobs='200',
              git_ref='refs/pull/1/head',
              fuchsia_ctl_version='version:0.0.2',
              build_host=True,
              build_fuchsia=True,
              build_android_aot=True,
              build_android_debug=True,
              android_sdk_license='android_sdk_hash',
              android_sdk_preview_license='android_sdk_preview_hash')),
  )

  yield api.test(
      'gcloud_pubsub_failure',
      api.buildbucket.ci_build(
          builder='Linux Host Engine',
          git_repo='https://github.com/flutter/engine',
          project='flutter'),
      # Next line force a fail condition for the bot update
      # first execution.
      api.step_data('gcloud pubsub', retcode=1),
      api.runtime(is_experimental=True),
      api.properties(
          InputProperties(
              clobber=False,
              git_url='https://github.com/flutter/engine',
              goma_jobs='200',
              git_ref='refs/pull/1/head',
              fuchsia_ctl_version='version:0.0.2',
              build_host=True,
              build_fuchsia=True,
              build_android_aot=True,
              build_android_debug=True,
              android_sdk_license='android_sdk_hash',
              android_sdk_preview_license='android_sdk_preview_hash')))
