# Copyright 2013 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.


DEPS = [
  "recipe_engine/buildbucket",
  "recipe_engine/context",
  "recipe_engine/path",
  "recipe_engine/platform",
  "recipe_engine/properties",
  "recipe_engine/raw_io",
  "recipe_engine/step",
  "git",
]


def RunSteps(api):
  url = "https://chromium.googlesource.com/chromium/src.git"

  # git.checkout can optionally dump GIT_CURL_VERBOSE traces to a log file,
  # useful for debugging git access issues that are reproducible only on bots.
  curl_trace_file = None
  if api.properties.get("use_curl_trace"):
    curl_trace_file = api.path.start_dir / "curl_trace.log"

  submodule_update_force = api.properties.get("submodule_update_force", False)
  submodule_update_recursive = api.properties.get(
    "submodule_update_recursive", True
  )

  # You can use api.git.checkout to perform all the steps of a safe checkout.
  revision = (
    api.buildbucket.gitiles_commit.ref or api.buildbucket.gitiles_commit.id
  )
  retVal = api.git.checkout(
    url,
    ref=revision,
    recursive=True,
    submodule_update_force=submodule_update_force,
    set_got_revision=api.properties.get("set_got_revision"),
    curl_trace_file=curl_trace_file,
    remote_name=api.properties.get("remote_name"),
    display_fetch_size=api.properties.get("display_fetch_size"),
    file_name=api.properties.get("checkout_file_name"),
    submodule_update_recursive=submodule_update_recursive,
    use_git_cache=api.properties.get("use_git_cache"),
    tags=api.properties.get("tags"),
    depth=api.properties.get("depth"),
    no_auto_gc=api.properties.get("no_auto_gc"),
    run_maintenance=api.properties.get("run_maintenance"),
  )

  assert retVal == "deadbeef", "expected retVal to be %r but was %r" % (
    "deadbeef",
    retVal,
  )

  # count_objects shows number and size of objects in .git dir.
  api.git.count_objects(
    name="count-objects",
    raise_on_failure=api.properties.get("count_objects_can_fail_build", False),
    git_config_options={"foo": "bar"},
  )

  # Get the remote URL.
  api.git.get_remote_url(
    step_test_data=lambda: api.raw_io.test_api.stream_output("foo")
  )

  api.git.get_timestamp(test_data="foo")

  # You can use api.git.fetch_tags to fetch all tags from the remote
  api.git.fetch_tags(api.properties.get("remote_name"))

  # If you need to run more arbitrary git commands, you can use api.git itself,
  # which behaves like api.step(), but automatically sets the name of the step.
  with api.context(cwd=api.path.checkout_dir):
    api.git("status")

  api.git("status", name="git status can_fail_build", raise_on_failure=True)

  api.git("status", name="git status cannot_fail_build", raise_on_failure=False)

  # You should run git new-branch before you upload something with git cl.
  api.git.new_branch("refactor")  # Upstream is origin/main by default.

  if api.properties.get("set_both_upstream_and_upstream_current"):
    api.git.new_branch(
      "failed_new_branch", upstream="will_fail", upstream_current=True
    )
  # And use upstream kwarg to set up different upstream for tracking.
  api.git.new_branch("feature", upstream="refactor")
  # A new branching tracking the current branch, which is 'feature'.
  api.git.new_branch("track_current", upstream_current=True)
  # You can use api.git.rebase to rebase the current branch onto another one
  api.git.rebase(
    name_prefix="my repo",
    branch="origin/main",
    dir_path=api.path.checkout_dir,
    remote_name=api.properties.get("remote_name"),
  )

  if api.properties.get("cat_file", None):
    step_result = api.git.cat_file_at_commit(
      api.properties["cat_file"], revision, stdout=api.raw_io.output()
    )
    if "TestOutput" in step_result.stdout.decode("utf-8"):
      pass  # Success!

  # Bundle the repository.
  api.git.bundle_create(api.path.start_dir / "all.bundle")


def GenTests(api):
  yield api.test("basic")
  yield api.test("basic_tags") + api.properties(tags=True)
  yield api.test("basic_ref") + api.buildbucket.ci_build(git_ref="refs/foo/bar")
  yield api.test("basic_branch") + api.buildbucket.ci_build(
    git_ref="refs/heads/testing"
  )
  yield api.test("basic_hash") + api.buildbucket.ci_build(
    revision="abcdef0123456789abcdef0123456789abcdef01", git_ref=None
  )
  yield api.test("basic_file_name") + api.properties(checkout_file_name="DEPS")
  yield api.test("basic_submodule_update_force") + api.properties(
    submodule_update_force=True
  )

  yield api.test("platform_win") + api.platform.name("win")

  yield (
    api.test("curl_trace_file")
    + api.properties(use_curl_trace=True)
    + api.buildbucket.ci_build(git_ref="refs/foo/bar")
  )

  yield (
    api.test("can_fail_build", status="INFRA_FAILURE")
    + api.step_data("git status can_fail_build", retcode=1)
  )

  yield (
    api.test("cannot_fail_build")
    + api.step_data("git status cannot_fail_build", retcode=1)
  )

  yield (api.test("set_got_revision") + api.properties(set_got_revision=True))

  yield (
    api.test("rebase_failed", status="INFRA_FAILURE")
    + api.step_data("my repo rebase", retcode=1)
  )

  yield api.test("remote_not_origin") + api.properties(remote_name="not_origin")

  yield (
    api.test("count-objects_delta") + api.properties(display_fetch_size=True)
  )

  yield (
    api.test("count-objects_failed") + api.step_data("count-objects", retcode=1)
  )

  yield (
    api.test("count-objects_with_bad_output")
    + api.step_data(
      "count-objects",
      stdout=api.raw_io.output(api.git.count_objects_output("xxx")),
    )
  )

  yield (
    api.test(
      "count-objects_with_bad_output_fails_build", status="INFRA_FAILURE"
    )
    + api.step_data(
      "count-objects",
      stdout=api.raw_io.output(api.git.count_objects_output("xxx")),
    )
    + api.properties(count_objects_can_fail_build=True)
  )
  yield (
    api.test("cat-file_test")
    + api.step_data(
      "git cat-file abcdef12345:TestFile",
      stdout=api.raw_io.output("TestOutput"),
    )
    + api.buildbucket.ci_build(revision="abcdef12345", git_ref=None)
    + api.properties(cat_file="TestFile")
  )

  yield (api.test("git-cache-checkout") + api.properties(use_git_cache=True))

  yield (
    api.test("new_branch_failed", status="INFRA_FAILURE")
    + api.properties(set_both_upstream_and_upstream_current=True)
    + api.expect_exception("ValueError")
  )

  yield (api.test("git-checkout-with-depth") + api.properties(depth=1))

  yield (
    api.test("git-fetch-without-auto-gc") + api.properties(no_auto_gc=True)
  )

  yield (
    api.test("git-fetch-with-maintenance")
    + api.properties(run_maintenance=True)
  )
