# Copyright 2021 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.

"""Flutter Engine builder recipe.

This recipe is used to build flavors of flutter engine identified by lists of
gn flags and ninja configs and targets.


The following are examples of valid configurations passed to builders using
this recipe in the builds property:

 {
    "gn" : [
       "--ios",
       "--runtime-mode",
       "debug",
       "--simulator",
       "--no-lto"
    ],
    "ninja": {
      "config": "ios_debug_sim",
      "targets": ["ios_test_flutter"]
    }
 }
"""
import copy

from contextlib import contextmanager

from google.protobuf import struct_pb2
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

DEPS = [
    'depot_tools/gsutil',
    'flutter/flutter_bcid',
    'flutter/build_util',
    'flutter/flutter_deps',
    'flutter/os_utils',
    'flutter/osx_sdk',
    'flutter/repo_util',
    'flutter/retry',
    'flutter/shard_util_v2',
    'flutter/test_utils',
    'fuchsia/cas_util',
    'recipe_engine/bcid_reporter',
    'recipe_engine/buildbucket',
    'recipe_engine/context',
    'recipe_engine/file',
    'recipe_engine/path',
    'recipe_engine/platform',
    'recipe_engine/properties',
    'recipe_engine/raw_io',
    'recipe_engine/step',
]

PROPERTIES = InputProperties
ENV_PROPERTIES = EnvProperties
ANDROID_ARTIFACTS_BUCKET = 'download.flutter.io'


def Build(api, checkout, env, env_prefixes, outputs):
  """Builds a flavor identified as a set of gn and ninja configs."""
  ninja_tool = {
      "ninja": api.build_util.build,
      "autoninja": api.build_util.build_autoninja,
  }
  deps = api.properties.get('dependencies', [])
  api.flutter_deps.required_deps(env, env_prefixes, deps)
  build = api.properties.get('build')
  api.flutter_bcid.report_stage('compile')
  api.build_util.run_gn(build.get('gn'), checkout)
  ninja = build.get('ninja')
  ninja_tool[ninja.get('tool', 'ninja')
            ](ninja.get('config'), checkout, ninja.get('targets'))
  # Archive full build. This is inneficient but necessary for global generators.
  full_build_hash = api.shard_util_v2.archive_full_build(
          checkout.join('out', build.get('name')), build.get('name'))
  outputs['full_build'] = full_build_hash
  generator_tasks = build.get('generators', {}).get('tasks', [])
  pub_dirs = build.get('generators', {}).get('pub_dirs', [])
  archives = build.get('archives', [])
  # Get only local tests.
  tests = [t for t in build.get('tests', []) if t.get('type') == 'local']
  with api.context(env=env, env_prefixes=env_prefixes,
                   cwd=checkout.join('flutter')):
    # Run pub on all of the pub_dirs.
    for pub in pub_dirs:
      pub_dir = api.path.abs_to_path(
          api.path.dirname(
              checkout.join(pub))
      )
      with api.context(env=env, env_prefixes=env_prefixes,
                       cwd=pub_dir):
        api.step('dart pub get', ['dart', 'pub', 'get'])
    for generator_task in generator_tasks:
      # Generators must run from inside flutter folder.
      cmd = []
      for script in generator_task.get('scripts'):
        full_path_script = checkout.join(script)
        cmd.append(full_path_script)
      cmd.extend(generator_task.get('parameters', []))
      api.step(generator_task.get('name'), cmd)
    # Run local tests in the builder to optimize resource usage.
    for test in tests:
      command = [test.get('language')] if test.get('language') else []
      # Ideally local tests should be completely hermetic and in theory we can run
      # them in parallel using futures. I haven't found a flutter engine
      # configuration with more than one local test but once we find it we
      # should run the list of tests using parallelism.
      # TODO(godofredoc): Optimize to run multiple local tests in parallel.
      command.append(checkout.join(test.get('script')))
      command.extend(test.get('parameters', []))
      #api.step(test.get('name'), command)
      step_name = api.test_utils.test_step_name(test.get('name'))

      def run_test():
        return api.step(step_name, command)

      # Rerun test step 3 times by default if failing.
      # TODO(keyonghan): notify tree gardener for test failures/flakes:
      # https://github.com/flutter/flutter/issues/89308
      api.retry.wrap(run_test, step_name=test.get('name'))

    api.flutter_bcid.report_stage('upload')
    for archive_config in archives:
      outputs[archive_config['name']] = Archive(api, checkout, archive_config)
    api.flutter_bcid.report_stage('upload-complete')


def Archive(api, checkout,  archive_config):
  archive_dir = api.path.mkdtemp(archive_config['name'])
  # First remove paths from excluding list.
  for exclude_path in archive_config.get('exclude_paths', []):
    full_exclude_path = api.path.abspath(checkout.join(exclude_path))
    api.file.rmtree('Remove %s' % exclude_path, full_exclude_path)
  # Mock a directory path to make tests pass.
  api.path.mock_add_directory(api.path.abspath(checkout.join('out/host_debug_unopt/')))
  api.path.mock_add_file(api.path.abspath(checkout.join('out/host_debug_unopt/file.zip')))

  # Android artifacts are uploaded to a different bucket. If they exist we need a second
  # gsutil upload.
  upload_android_artifacts = False
  for include_path in archive_config.get('include_paths', []):
    full_include_path = api.path.abspath(checkout.join(include_path))
    if include_path.endswith(ANDROID_ARTIFACTS_BUCKET):
      upload_android_artifacts = True
    if api.path.isdir(full_include_path):
      dir_name = api.path.basename(full_include_path)
      api.file.copytree('Copy %s' % include_path, full_include_path, archive_dir.join(dir_name))
    else:
      dir_name = api.path.dirname(full_include_path)
      full_base_path = api.path.abspath(checkout.join(archive_config.get('base_path','')))
      rel_path = api.path.relpath(dir_name, full_base_path)
      rel_path = '' if rel_path == '.' else rel_path
      base_name = api.path.basename(full_include_path)
      api.file.ensure_directory('Ensuring %s' % archive_dir.join(rel_path), archive_dir.join(rel_path))
      api.file.copy('Copy %s' % include_path, full_include_path, archive_dir.join(rel_path, base_name))
  if archive_config.get('type') == 'gcs' and archive_config.get('include_paths', []):
    bucket = 'flutter_archives_v2'
    if api.buildbucket.gitiles_commit.project == 'monorepo':
      commit = api.repo_util.get_commit(checkout.join('../../monorepo'))
      artifact_prefix = 'monorepo/'
    else:
      commit = api.repo_util.get_commit(checkout.join('flutter'))
      artifact_prefix = ''
    artifact_path = '%sflutter_infra_release/flutter/%s/' % (artifact_prefix,
                                                               commit)
    api.gsutil.upload(
        source='%s/*' % archive_dir,
        bucket=bucket,
        dest=artifact_path,
        args=['-r'],
        name=archive_config['name'],
    )
    for local_filepath in api.file.glob_paths('Generate provenance', archive_dir, '*', test_data=('file.txt',)):
      remote_filepath = 'gs://%s/%s/%s' % (bucket, artifact_path, api.path.basename(str(local_filepath)))
      api.flutter_bcid.upload_provenance(local_filepath, remote_filepath)
    # Jar and pom files are uploaded to download.flutter.io while all the other artifacts
    # are uploaded to flutter_infra_release. If we override paths artifacts need to be organized
    # as gs://<overriden_bucket>/flutter_infra_release for non android artifacts and
    # gs://<overriden_bucket>/download.flutter.io for android artifacts.
    if upload_android_artifacts:
      android_artifact_path = artifact_prefix
      api.gsutil.upload(
          source='%s/%s/' % (archive_dir, ANDROID_ARTIFACTS_BUCKET),
          bucket=bucket,
          dest=android_artifact_path,
          args=['-r'],
          name=archive_config['name'],
      )
      for local_filepath in api.file.glob_paths('Generate provenance', archive_dir,
        'download.flutter.io/*', test_data=('file.txt',)):
        remote_filepath = 'gs://%s/%s/%s' % (bucket, artifact_path,
          api.path.basename(str(local_filepath)))
        api.flutter_bcid.upload_provenance(local_filepath, remote_filepath)
    return 'gs://%s/%s/%s' % ( bucket, artifact_path, api.path.basename(archive_dir))
  # Archive using CAS by default
  return api.cas_util.upload(archive_dir, step_name='Archive %s' % archive_config['name'])


def RunSteps(api, properties, env_properties):
  api.flutter_bcid.report_stage('start')
  checkout = api.path['cache'].join('builder', 'src')
  api.file.rmtree('Clobber build output', checkout.join('out'))
  cache_root = api.path['cache'].join('builder')
  api.file.ensure_directory('Ensure checkout cache', cache_root)

  # Enable long path support on Windows.
  api.os_utils.enable_long_paths()
  env, env_prefixes = api.repo_util.engine_environment(api.path['cache'].join('builder'))

  # Engine path is used inconsistently across the engine repo. We'll start
  # with [cache]/builder and will adjust it to start using it consistently.
  env['ENGINE_PATH'] = api.path['cache'].join('builder')

  custom_vars = api.properties.get('gclient_custom_vars', {})
  clobber = api.properties.get('clobber', False)
  api.flutter_bcid.report_stage('fetch')
  if api.buildbucket.gitiles_commit.project == 'monorepo':
    api.repo_util.monorepo_checkout(
        cache_root, env, env_prefixes, clobber=clobber, custom_vars=custom_vars
    )
    checkout = api.path['cache'].join('builder', 'engine', 'src')
  else:
    api.repo_util.engine_checkout(
        cache_root, env, env_prefixes, clobber=clobber, custom_vars=custom_vars
    )
  outputs = {}
  if api.platform.is_mac:
    with api.osx_sdk('ios'):
      Build(api, checkout, env, env_prefixes, outputs)
  else:
    Build(api, checkout, env, env_prefixes, outputs)
  output_props = api.step('Set output properties', None)
  output_props.presentation.properties['cas_output_hash'] = outputs


def GenTests(api):
  build = {
      "archives": [
          {
              "name": "host_debug_unopt",
              "type": "cas",
              "include_paths": ['out/host_debug_unopt/', 'out/host_debug_unopt/file.zip',
                                'out/host_debug_unopt/download.flutter.io'],
              "exclude_paths": ['out/host_debug_unopt/obj', 'out/host_debug_unopt/stripped.exe']
          }
      ],
      "gn": ["--ios"], "ninja": {"config": "ios_debug", "targets": []},
      "generators": {
          "pub_dirs": ["dev"],
          "tasks": [
              {
                  "name": "generator1",
                  "scripts": ["script1.sh", "dev/felt.dart"],
                  "parameters": ["--argument1"]
              }
          ]
      },
      "tests": [
          {
               "name": "mytest", "script": "myscript.sh",
               "parameters": ["param1", "param2"], "type": "local"
          }
      ]
  }
  yield api.test('basic', api.properties(build=build, no_goma=True))
  yield api.test(
      'mac', api.properties(build=build, no_goma=True),
      api.platform('mac', 64),
  )
  yield api.test(
      'monorepo', api.properties(build=build, no_goma=True),
      api.buildbucket.ci_build(
          project='dart',
          bucket='ci.sandbox',
          git_repo='https://dart.googlesource.com/monorepo',
          git_ref='refs/heads/main'
      ),
  )
  build_custom = dict(build)
  build_custom["gclient_custom_vars"] = {"example_custom_var": True}
  build_custom["tests"] = []
  yield api.test(
      'dart-internal-flutter', api.properties(build=build, no_goma=True),
      api.buildbucket.ci_build(
          project='dart-internal',
          bucket='flutter',
          git_repo='https://flutter.googlesource.com/mirrors/engine',
          git_ref='refs/heads/main'
      ),
  )
  build_custom = dict(build)
  build_custom["gclient_custom_vars"] = {"example_custom_var": True}
  build_custom["tests"] = []
  yield api.test(
      'basic_custom_vars', api.properties(build=build_custom)
  )
  # gcs archives
  build_gcs = copy.deepcopy(build)
  build_gcs['archives'][0]['type'] = 'gcs'
  yield api.test(
      'basic_gcs', api.properties(build=build_gcs, no_goma=True),
      api.step_data(
          'git rev-parse',
          stdout=api.raw_io
          .output_text('12345abcde12345abcde12345abcde12345abcde\n')
      )
  )
  yield api.test(
      'monorepo_gcs', api.properties(build=build_gcs, no_goma=True),
      api.buildbucket.ci_build(
          project='dart',
          bucket='ci.sandbox',
          git_repo='https://dart.googlesource.com/monorepo',
          git_ref='refs/heads/main'
      ),
      api.step_data(
          'git rev-parse',
          stdout=api.raw_io
          .output_text('12345abcde12345abcde12345abcde12345abcde\n')
      )
  )
