# 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/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/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


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

    for archive_config in archives:
      outputs[archive_config['name']] = Archive(api, checkout, archive_config)


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('download.flutter.io'):
      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'],
    )
    # 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/download.flutter.io/' % archive_dir,
          bucket=bucket,
          dest=android_artifact_path,
          args=['-r'],
          name=archive_config['name'],
      )
    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):
  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(checkout)

  # 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)
  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, goma_jobs="100"))
  yield api.test(
      'mac', api.properties(build=build, goma_jobs="100"),
      api.platform('mac', 64),
  )
  yield api.test(
      'monorepo', api.properties(build=build, goma_jobs="100"),
      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(
      'basic_custom_vars', api.properties(build=build_custom, goma_jobs="100")
  )
  # gcs archives
  build_gcs = copy.deepcopy(build)
  build_gcs['archives'][0]['type'] = 'gcs'
  yield api.test(
      'basic_gcs', api.properties(build=build_gcs, goma_jobs="100"),
      api.step_data(
          'git rev-parse',
          stdout=api.raw_io
          .output_text('12345abcde12345abcde12345abcde12345abcde\n')
      )
  )
  yield api.test(
      'monorepo_gcs', api.properties(build=build_gcs, goma_jobs="100"),
      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')
      )
  )
