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

DEPS = [
  'depot_tools/bot_update',
  'depot_tools/depot_tools',
  'depot_tools/gclient',
  'goma',
  'recipe_engine/context',
  'recipe_engine/file',
  'recipe_engine/path',
  'recipe_engine/platform',
  'recipe_engine/properties',
  'recipe_engine/python',
  'recipe_engine/runtime',
  'recipe_engine/step',
]

def KillTasks(api, checkout_dir, ok_ret='any'):
  """Kills leftover tasks from previous runs or steps."""
  dart_sdk_dir = checkout_dir.join('third_party', 'dart')
  api.python('kill processes',
               dart_sdk_dir.join('tools', 'task_kill.py'),
               ok_ret=ok_ret)

def Build(api, checkout_dir, config, *targets):
  build_dir = checkout_dir.join('out/%s' % config)
  ninja_cmd = [api.depot_tools.ninja_path, '-j', api.goma.jobs, '-C', build_dir]
  ninja_cmd.extend(targets)
  api.goma.build_with_goma(
    name='build %s' % ' '.join([config] + list(targets)),
    ninja_command=ninja_cmd)

def RunGN(api, checkout_dir, *args):
  gn_cmd = [checkout_dir.join('flutter/tools/gn')]
  gn_cmd.extend(args)
  # Flutter's gn tool needs ninja in the PATH
  with api.depot_tools.on_path():
    api.step('gn %s' % ' '.join(args), gn_cmd)

def AnalyzeDartUI(api, checkout_dir):
  with api.context(cwd=checkout_dir):
    api.step('analyze dart_ui', ['/bin/bash', 'flutter/ci/analyze.sh'])

def TestEngine(api, checkout_dir):
  with api.context(cwd=checkout_dir):
    api.step('test engine', ['/bin/bash', 'flutter/testing/run_tests.sh'])

def BuildLinuxAndroidx86(api, checkout_dir):
  for x86_variant in ['x64', 'x86']:
    RunGN(api, checkout_dir, '--android', '--android-cpu=' + x86_variant)
    Build(api, checkout_dir, 'android_debug_' + x86_variant)

def BuildLinuxAndroidArm(api, checkout_dir):
  RunGN(api, checkout_dir, '--android')
  Build(api, checkout_dir, 'android_debug')
  Build(api, checkout_dir, 'android_debug', ':dist')
  RunGN(api, checkout_dir, '--android', '--runtime-mode=release', '--android-cpu=arm')
  Build(api, checkout_dir, 'android_release', 'gen_snapshot')

  # Build and upload engines for the runtime modes that use AOT compilation.
  for runtime_mode in ['profile', 'release']:
    build_output_dir = 'android_' + runtime_mode

    RunGN(api, checkout_dir, '--android', '--runtime-mode=' + runtime_mode)
    Build(api, checkout_dir, build_output_dir)

def BuildLinux(api, checkout_dir):
  RunGN(api, checkout_dir)
  Build(api, checkout_dir, 'host_debug')
  RunGN(api, checkout_dir, '--unoptimized')
  Build(api, checkout_dir, 'host_debug_unopt')
  RunGN(api, checkout_dir, '--runtime-mode=release', '--dynamic')
  Build(api, checkout_dir, 'host_dynamic_release', 'flutter/lib/snapshot')
  # analyze step needs dart ui sources
  Build(api, checkout_dir, 'host_debug_unopt', 'generate_dart_ui')

def TestObservatory(api, checkout_dir):
  flutter_tester_path = checkout_dir.join('out/host_debug/flutter_tester')
  empty_main_path = checkout_dir.join(
      'flutter/shell/testing/observatory/empty_main.dart')
  test_path = checkout_dir.join('flutter/shell/testing/observatory/test.dart')
  test_cmd = ['dart', test_path, flutter_tester_path, empty_main_path]
  with api.context(cwd=checkout_dir):
    api.step('test observatory and service protocol', test_cmd)

def GetCheckout(api):
  src_cfg = api.gclient.make_config()
  src_cfg.target_os = set(['android'])
  src_cfg.revisions = {
    'src/flutter': api.properties.get('rev_engine') or
                   api.properties.get('revision') or 'HEAD',
    'src/third_party/dart': api.properties.get('rev_sdk') or 'HEAD',
    'flutter': api.properties.get('rev_flutter') or 'HEAD',
  }

  soln = src_cfg.solutions.add()
  soln.name = 'src/flutter'
  soln.url = \
      'https://chromium.googlesource.com/external/github.com/flutter/engine'

  soln = src_cfg.solutions.add()
  soln.name = 'flutter'
  soln.url = \
      'https://chromium.googlesource.com/external/github.com/flutter/flutter'

  api.gclient.c = src_cfg
  api.bot_update.ensure_checkout()
  api.gclient.runhooks()

  api.step('3xHEAD Flutter Hooks',
      ['src/third_party/dart/tools/3xhead_flutter_hooks.sh'])

def CopyArtifacts(api, engine_src, cached_dest, file_paths):
  for path in file_paths:
    if isinstance(path, tuple):
      # Second item is explicitly specified target file name
      source, target = path[0], path[1]
    else:
      source, target = path, api.path.basename(path)

    api.file.remove('remove %s' % target, cached_dest.join(target))
    api.file.copy('copy %s' % target, engine_src.join(source), cached_dest.join(target))

def UpdateCachedEngineArtifacts(api, flutter, engine_src):
  ICU_DATA_PATH = 'third_party/icu/flutter/icudtl.dat'
  CopyArtifacts(api, engine_src,
    flutter.join('bin', 'cache', 'artifacts', 'engine', 'linux-x64'),
    [ICU_DATA_PATH,
    'out/host_debug_unopt/flutter_tester',
    # Flutter debug and dynamic profile modes for all target platforms use Dart
    # RELEASE VM snapshot that comes from host debug build and has the metadata
    # related to development tools.
    'out/host_debug_unopt/gen/flutter/lib/snapshot/isolate_snapshot.bin',
    'out/host_debug_unopt/gen/flutter/lib/snapshot/vm_isolate_snapshot.bin',
    'out/host_debug_unopt/gen/frontend_server.dart.snapshot',
    # Flutter dynamic release mode for all target platforms uses Dart PRODUCT
    # VM snapshot from host dynamic release build that strips out the metadata
    # related to development tools.
    ('out/host_dynamic_release/gen/flutter/lib/snapshot/isolate_snapshot.bin',
     'product_isolate_snapshot.bin'),
    ('out/host_dynamic_release/gen/flutter/lib/snapshot/vm_isolate_snapshot.bin',
     'product_vm_isolate_snapshot.bin'),
    ]
  )

  CopyArtifacts(api, engine_src,
    flutter.join('bin', 'cache', 'artifacts', 'engine', 'android-arm-release', 'linux-x64'),
    ['out/android_release/clang_x86/gen_snapshot'])

  flutter_patched_sdk = flutter.join('bin', 'cache', 'artifacts', 'engine', 'common', 'flutter_patched_sdk')
  dart_sdk = flutter.join('bin', 'cache', 'dart-sdk')
  # In case dart-sdk symlink was left from previous run we need to [remove] it,
  # rather than [rmtree] because rmtree is going to remove symlink target folder.
  # We are not able to use api.file classes for this because there is no
  # support for symlink checks or handling of error condition.
  api.step('cleanup dart-sdk', [
    '/bin/bash', '-c', 'if [ -L "%(dir)s" ]; then rm "%(dir)s"; else rm -rf "%(dir)s"; fi' %
    {'dir': dart_sdk}])
  api.step('cleanup flutter_patched_sdk', [
    '/bin/bash', '-c', 'if [ -L "%(dir)s" ]; then rm "%(dir)s"; else rm -rf "%(dir)s"; fi' %
    {'dir': flutter_patched_sdk}])
  api.file.symlink('make cached dart-sdk point to just built dart sdk',
    engine_src.join('out', 'host_debug', 'dart-sdk'), dart_sdk)
  api.file.symlink('make cached flutter_patched_sdk point to just built flutter_patched_sdk',
    engine_src.join('out', 'host_debug', 'flutter_patched_sdk'), flutter_patched_sdk)

  # In case there is a cached version of "flutter_tools.snapshot" we have to
  # delete it.
  flutter_tools_snapshot = flutter.join('bin', 'cache', 'flutter_tools.snapshot')
  api.step('cleanup', [
    '/bin/bash', '-c', 'if [ -f "%(file)s" ]; then rm "%(file)s"; fi' %
    {'file': flutter_tools_snapshot}])

def TestFlutter(api, start_dir, just_built_dart_sdk):
  engine_src = start_dir.join('src')
  flutter = start_dir.join('flutter')
  flutter_cmd = flutter.join('bin/flutter')
  test_args = [
      '--local-engine=host_debug',
      '--local-engine-src-path=%s' % engine_src,
  ]
  test_cmd = [
    'dart', 'dev/bots/test.dart',
  ]
  api.step('disable flutter analytics', [flutter_cmd, 'config', '--no-analytics'])
  with api.context(cwd=flutter):
    api.step('flutter update-packages',
             [flutter_cmd, 'update-packages'] + test_args)

    # analyze.dart and test.dart have hardcoded references to bin/cache/dart-sdk.
    # So we overwrite bin/cache/dart-sdk and tightly-coupled frontend_server.dart.snapshot
    # with links that point to corresponding entries from binaries generated into
    # [engine_src]
    UpdateCachedEngineArtifacts(api, flutter, engine_src)

    # runs all flutter tests similar to Cirrus as described on this page:
    # https://github.com/flutter/flutter/blob/master/CONTRIBUTING.md
    api.step('flutter analyze', ['dart', 'dev/bots/analyze.dart',
             '--dart-sdk', just_built_dart_sdk
             ], timeout=20*60) # 20 minutes
    api.step('flutter test', test_cmd + test_args, timeout=90*60) # 90 minutes

def RunSteps(api):
  if api.runtime.is_luci:
    start_dir = api.path['cache'].join('builder')
  else:
    start_dir = api.path['start_dir']

  with api.context(cwd=start_dir):
    # buildbot sets 'clobber' to the empty string which is falsey, check with 'in'
    if 'clobber' in api.properties:
      api.file.rmcontents('everything', start_dir)
    GetCheckout(api)

  api.goma.ensure_goma()

  checkout_dir = start_dir.join('src')
  KillTasks(api, checkout_dir)
  try:
    BuildAndTest(api, start_dir, checkout_dir)
  finally:
    # TODO(aam): Go back to `ok_ret={0}` once dartbug.com/35549 is fixed
    KillTasks(api, checkout_dir, ok_ret='any')

def BuildAndTest(api, start_dir, checkout_dir):
  run_env = {
    'GOMA_DIR':api.goma.goma_dir,
    # By setting 'ANALYZER_STATE_LOCATION_OVERRIDE' we force analyzer to emit
    # its cached state into the given folder. If something goes wrong with
    # the cache we can clobber it by requesting normal clobber via Buildbot
    # UI.
    'ANALYZER_STATE_LOCATION_OVERRIDE': start_dir.join('.dartServer')
  }
  with api.context(cwd=start_dir, env=run_env):
    BuildLinux(api, checkout_dir)
    prebuilt_dart_bin = checkout_dir.join('third_party', 'dart', 'tools',
      'sdks', 'dart-sdk', 'bin')
    engine_env = { 'PATH': api.path.pathsep.join((str(prebuilt_dart_bin),
      '%(PATH)s')) }
    just_built_dart_sdk = checkout_dir.join('out', 'host_debug', 'dart-sdk')
    flutter_env = {
      'PATH': api.path.pathsep.join((str(just_built_dart_sdk.join('bin')), '%(PATH)s')),
      # Prevent test.dart from using git merge-base to determine a fork point.
      # git merge-base doesn't work without a FETCH_HEAD, which isn't available
      # on the first run of a bot. The builder tests a single revision, so use
      # rev_flutter.
      'TEST_COMMIT_RANGE': api.properties.get('rev_flutter') or 'HEAD'
    }

    with api.step.defer_results():
      # The context adds prebuilt dart-sdk to the path.
      with api.context(env=engine_env):
        AnalyzeDartUI(api, checkout_dir)
        TestEngine(api, checkout_dir)
        TestObservatory(api, checkout_dir)
        BuildLinuxAndroidArm(api, checkout_dir)
        BuildLinuxAndroidx86(api, checkout_dir)
      # The context adds freshly-built engine's dart-sdk to the path.
      with api.context(env=flutter_env):
        TestFlutter(api, start_dir, just_built_dart_sdk)

def GenTests(api):
  yield (api.test('flutter-engine-linux-buildbot') + api.platform('linux', 64)
      + api.properties(mastername='client.dart.internal',
            buildername='flutter-engine-linux',
            bot_id='fake-m1', clobber='',
            rev_sdk='foo', rev_engine='bar')
      + api.runtime(is_luci=False, is_experimental=False))
  yield (api.test('flutter-engine-linux') + api.platform('linux', 64)
      + api.properties(mastername='client.dart.internal',
            buildername='flutter-engine-linux',
            bot_id='fake-m1', clobber='',
            rev_sdk='foo', rev_engine='bar')
      + api.runtime(is_luci=True, is_experimental=False))
