# 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

PYTHON_VERSION_COMPATIBILITY = 'PY3'

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')

PROPERTIES = InputProperties
ENV_PROPERTIES = EnvProperties


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')

  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')))
