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

import re

from recipe_engine.post_process import (
    DoesNotRun,
    MustRun,
    StepCommandContains,
    StepCommandDoesNotContain,
)

DEPS = [
    'depot_tools/gclient',
    'recipe_engine/context',
    'recipe_engine/buildbucket',
    'recipe_engine/path',
    'recipe_engine/runtime',
    'recipe_engine/step',
]

# https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
SEMANTIC_VERSION_PATTERN = r'^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$'

PYTHON_VERSION_COMPATIBILITY = "PY3"


def _is_modern_version(version):
  match = re.match(SEMANTIC_VERSION_PATTERN, version)
  if not match:
    return False
  major = int(match['major'])
  minor = int(match['minor'])
  return 3 <= major or (2 == major and 16 <= minor)


def RunSteps(api):
  ref = api.buildbucket.gitiles_commit.ref
  channel = 'dev' if '.dev' in ref else 'beta' if '.beta' in ref else 'stable'
  version = ref.split('/')[-1]
  if not _is_modern_version(version):
    api.step.empty('%s is not a modern Dart SDK version' % version)
    return
  api.gclient.set_config('dart')
  api.gclient.checkout(extra_sync_flags=["--revision", ref])
  with api.context(cwd=api.path['start_dir'].join('sdk')):
    command = [
        'python3', 'tools/promote.py', '--channel', channel, '--version',
        version, 'promote'
    ]
    if api.runtime.is_experimental:
      command.append('--dry')
    api.step('promote', command)
  api.buildbucket.schedule(
      [api.buildbucket.schedule_request(builder="chocolatey")],
      step_name='trigger chocolatey')


def GenTests(api):
  yield api.test(
      'dev',
      api.buildbucket.ci_build(
          project='dart-internal',
          builder='promote',
          git_repo='https://dart.googlesource.com/sdk',
          git_ref="refs/tags/2.17.0-99.0.dev",
          revision='543ef2005f24402b267f307ccc90a5287262703f'),
      api.post_process(StepCommandContains, 'promote',
                       ['--channel', 'dev', '--version', '2.17.0-99.0.dev']),
      api.post_process(StepCommandDoesNotContain, 'promote', ['--dry']),
      api.post_process(MustRun, 'trigger chocolatey'),
  )
  yield api.test(
      'beta',
      api.buildbucket.ci_build(
          project='dart-internal',
          builder='promote',
          git_repo='https://dart.googlesource.com/sdk',
          git_ref="refs/tags/2.17.0-69.1.beta",
          revision='65d0119b53e9f69e73aa47a779c3bc24bba1f9ce'),
      api.post_process(StepCommandContains, 'promote',
                       ['--channel', 'beta', '--version', '2.17.0-69.1.beta']),
      api.post_process(StepCommandDoesNotContain, 'promote', ['--dry']),
      api.post_process(MustRun, 'trigger chocolatey'),
  )
  yield api.test(
      'dry',
      api.runtime(is_experimental=True),
      api.buildbucket.ci_build(
          project='dart-internal',
          builder='promote',
          git_repo='https://dart.googlesource.com/sdk',
          git_ref="refs/tags/2.16.0",
          revision='547d54e13cc8c1ce9279792fd16c189663e18f96'),
      api.post_process(
          StepCommandContains, 'promote',
          ['--channel', 'stable', '--version', '2.16.0', 'promote', '--dry']),
      api.post_process(MustRun, 'trigger chocolatey'),
  )
  yield api.test(
      'invalid',
      api.buildbucket.ci_build(
          project='dart-internal',
          builder='promote',
          git_repo='https://dart.googlesource.com/sdk',
          git_ref="refs/tags/analyzer-0.32.0",
          revision='e6d9ed5688a0fc60ab8f2a3f619fc877f23a350e'),
      api.post_process(MustRun,
                       'analyzer-0.32.0 is not a modern Dart SDK version'),
      api.post_process(DoesNotRun, 'promote'),
      api.post_process(DoesNotRun, 'trigger chocolatey'),
  )
  yield api.test(
      'old',
      api.buildbucket.ci_build(
          project='dart-internal',
          builder='promote',
          git_repo='https://dart.googlesource.com/sdk',
          git_ref="refs/tags/2.15.0",
          revision='da9b3409e6a546202700457d33b56b922c099abc'),
      api.post_process(MustRun, '2.15.0 is not a modern Dart SDK version'),
      api.post_process(DoesNotRun, 'promote'),
      api.post_process(DoesNotRun, 'trigger chocolatey'),
  )
