# Copyright 2020 The Fuchsia 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 collections
import os

from recipe_engine import recipe_api

# Used to get the remote for dart sdk
DART_SDK_PROJECT = 'dart/sdk'

COMMIT_MESSAGE = """\
[roll] Update {deps}

{logs}

Cq-Cl-Tag: roller-builder:{builder}
Cq-Cl-Tag: roller-bid:{build_id}
CQ-Do-Not-Cancel-Tryjobs: true"""


class DartApi(recipe_api.RecipeApi):
  """APIs to work with Dart repo and Dart packages."""

  def run_update_3p_packages(self, checkout_root):
    """Runs update_3p_packages.py in dart 3p repo checkout.

    Args:
      checkout_root (Path): The root path to the project checkouts.
    """
    self.m.python(
        'update dart 3p packages',
        checkout_root.join('scripts', 'dart', 'update_3p_packages.py'),
        args=['--debug'],
    )

  def update_3p_packages(self, checkout_root, dry_run=False):
    """Updates fuchsia's third-party dart packages.

    Args:
      checkout_root (Path): Root path to checkouts.
      dry_run (bool): Whether the roll will be allowed to complete or not.

    Returns:
      A string with third_party/dart-pkg/pub latest commit hash.
    """
    commit_msg = '[roll] Update third-party dart packages'
    packages_root = checkout_root.join('third_party', 'dart-pkg', 'pub')
    with self.m.context(cwd=packages_root):
      # Make sure third_party/dart-pkg is at origin/master before running the
      # update script to catch any manual commits that extend past the revision at
      # integration's HEAD.
      self.m.git('fetch', 'origin')
      self.m.git('checkout', 'origin/master')
      current_hash = self.m.git.get_hash()
      self.run_update_3p_packages(checkout_root)
      rolled = self.m.auto_roller.attempt_roll(
          gerrit_project='third_party/dart-pkg/pub',
          repo_dir=packages_root,
          commit_message=commit_msg,
          dry_run=dry_run)
      current_hash = self.m.git.get_hash()
    self.m.step.active_result.presentation.logs['revision'] = [current_hash]
    return current_hash

  def update_pkg_manifest(self, path, checkout_root):
    """Overwrites a dart third party package manifest.

    Args:
      path (Path): A path to the dart/sdk repository.
      checkout_root (Path): A path to where the integration project
        was checked out.
    """
    manifest_path = checkout_root.join('fuchsia', 'topaz',
                                       'dart_third_party_pkg')
    self.m.python(
        name='update %s' % self.m.path.basename(manifest_path),
        script=path.join('tools', 'create_pkg_manifest.py'),
        args=['-d', path.join('DEPS'), '-o', manifest_path],
    )

  def checkout(self, path, revision=None):
    """Get dart/sdk.

    Args:
      path (Path): Location where dart source code will be checked out.
      revision (str): The revision of the source code to check out.
    """
    deps_info = self.m.jiri.project([DART_SDK_PROJECT])
    remote = deps_info.json.output[0]['remote']
    self.m.git.checkout(
        url=remote,
        path=path,
        ref=revision,
    )
