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

"""
Recipe to build GCE images with Packer.
"""

from recipe_engine.recipe_api import Property

import re

DEPS = [
    "fuchsia/buildbucket_util",
    "fuchsia/git",
    "fuchsia/git_checkout",
    "recipe_engine/context",
    "recipe_engine/file",
    "recipe_engine/futures",
    "recipe_engine/path",
    "recipe_engine/properties",
    "recipe_engine/raw_io",
    "recipe_engine/step",
]

PROPERTIES = {
    "repo":
        Property(kind=str, help="Salt repository to checkout."),
    "dry_run":
        Property(
            kind=bool,
            help="Exit early instead of creating a disk image.",
            default=True
        ),
}
TEMPLATE_SUFFIX = ".packer.generated.json"


def RunSteps(api, repo, dry_run):
  salt_path, revision = api.git_checkout(repo, rebase_merges=True)

  # Get a short revision, image names must be < 64 characters
  with api.context(cwd=salt_path):
    revision = api.git(
        "git rev-parse",
        "rev-parse",
        "--short",
        revision,
        stdout=api.raw_io.output_text(),
    ).stdout.rstrip()

  packer_dir = salt_path.join("packer")
  template_paths = api.file.glob_paths(
      "find packer templates", packer_dir, "*" + TEMPLATE_SUFFIX
  )

  env = {
      # Disable update checks.
      "CHECKPOINT_DISABLE": "1",
      # Enable verbose logging.
      "PACKER_LOG": "1",
      # Disable color in logging.
      "PACKER_NO_COLOR": "1",
  }

  with api.context(env=env, cwd=salt_path):
    builds = []
    for template_path in template_paths:
      api.step(
          "packer validate",
          [
              "packer",
              "validate",
              "-var",
              "revision={}".format(revision),
              template_path,
          ],
      )
      builds.append(
          api.futures.spawn(
              _do_packer_builder,
              api,
              revision,
              dry_run,
              template_path,
          )
      )
    api.futures.wait(builds)
    if any(not build.result() for build in builds):
      raise api.step.StepFailure("BUILDS FAILED")


def _do_packer_builder(api, revision, dry_run, template_path):
  build = api.path.basename(template_path).replace(TEMPLATE_SUFFIX, "")
  with api.step.nest(build):
    result = api.step(
        "packer build",
        [
            "packer",
            "build",
            "-var",
            "revision={}".format(revision),
            "-var",
            "dry_run={}".format(str(dry_run).lower()),
            "-var",
            "use_internal_ip=true",
            "-only={}".format(build),
            template_path,
        ],
        stdout=api.raw_io.output_text(),
        ok_ret="any",
        # By default recipe_engine assigns a `cost` of 500 mCPU per step,
        # this limits our parallelism to 2*NUM_CORES but these steps are
        # simply waiting 99% of the time we can run far more in parallel.
        cost=None,
    )
    output = result.stdout
    result.presentation.logs["output"] = output.splitlines()

    if result.retcode != 0:
      if dry_run:
        for line in output.splitlines():
          if "DRYRUN SUCCEEDED" in line:
            result.presentation.step_text = "DRYRUN SUCCEEDED"
            return True
        result.presentation.step_text = "DRYRUN FAILED"
        result.presentation.status = api.step.FAILURE
      result.presentation.status = api.step.FAILURE
    else:
      return True
    if result.presentation.status == api.step.FAILURE:
      failures_regex = re.compile(
          "(\s*ID:\s(.*?\n).*?Result:\sFalse\n.*?Changes:.*?)\n\s*{}:\s-{{10}}"
          .format(build),
          re.DOTALL | re.MULTILINE,
      )
      for f in re.findall(failures_regex, output):
        result.presentation.logs[f[1]] = f[0].splitlines()
      return False


def GenTests(api):
  state_failures = """
     fail: ----------
     fail:           ID: /etc/systemd/system/gce-provider-start-agent.service
     fail:     Function: file.managed
     fail:       Result: False
     fail:      Comment: The following requisites were not found:
     fail:                                  require:
     fail:                                      user: swarming_use
     fail:      Started: 01:13:41.861499
     fail:     Duration: 0.028 ms
     fail:      Changes:
     fail: ----------
     fail:           ID: gce-provider-start-agent
     fail:     Function: service.enabled
     fail:       Result: False
     fail:      Comment: One or more requisite failed: luci.gce_provider./etc/systemd/system/gce-provider-start-agent.service
     fail:      Started: 01:13:41.862762
     fail:     Duration: 0.017 ms
     fail:      Changes:
     fail: ----------
     fail:           ID: curl
     fail:     Function: pkg.installed
     fail:       Result: True
     fail:      Comment: All specified packages are already installed
     fail:      Started: 01:13:41.868646
     fail:     Duration: 688.753 ms
     fail:      Changes:
     fail: ----------
     """

  repo = "https://dash-internal.googlesource.com/salt"
  yield (
      api.buildbucket_util.test("ci_failure", status="FAILURE", git_repo=repo) +
      api.properties(repo=repo, dry_run=False) + api.step_data(
          "find packer templates",
          api.file.glob_paths([
              "pass.packer.generated.json",
              "fail.packer.generated.json",
          ]),
      ) + api.step_data("pass.packer build", retcode=0) + api.step_data(
          "fail.packer build",
          api.raw_io.stream_output_text(state_failures),
          retcode=1,
      )
  )

  yield (
      api.buildbucket_util.test("ci_success", git_repo=repo) +
      api.properties(repo=repo, dry_run=False) + api.step_data(
          "find packer templates",
          api.file.glob_paths([
              "pass.packer.generated.json",
          ]),
      ) + api.step_data("pass.packer build", retcode=0)
  )

  yield (
      api.buildbucket_util.test("try_failure", status="FAILURE", git_repo=repo)
      + api.properties(repo=repo, dry_run=True) + api.step_data(
          "find packer templates",
          api.file.glob_paths([
              "pass.packer.generated.json",
              "fail.packer.generated.json",
          ]),
      ) + api.step_data("pass.packer build", retcode=0) + api.step_data(
          "fail.packer build",
          api.raw_io.stream_output_text(state_failures),
          retcode=1,
      )
  )

  yield (
      api.buildbucket_util.test("try_success", tryjob=True, git_repo=repo) +
      api.properties(repo=repo, dry_run=True) + api.step_data(
          "find packer templates",
          api.file.glob_paths([
              "pass.packer.generated.json",
          ]),
      ) + api.step_data(
          "pass.packer build",
          api.raw_io.stream_output_text("DRYRUN SUCCEEDED"),
          retcode=1,
      )
  )
