# 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_path = checkout.join('flutter', 'third_party', 'ninja', 'ninja')
  ninja_args = [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 = ['python3', 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', '--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')))
