# Copyright 2016 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 for building Jiri."""

from PB.recipes.fuchsia.jiri import InputProperties

DEPS = [
    "fuchsia/buildbucket_util",
    "fuchsia/checkout",
    "fuchsia/cipd_util",
    "fuchsia/go",
    "fuchsia/gsutil",
    "fuchsia/jiri",
    "recipe_engine/buildbucket",
    "recipe_engine/context",
    "recipe_engine/path",
    "recipe_engine/properties",
    "recipe_engine/step",
    "recipe_engine/time",
]

PROPERTIES = InputProperties

# The current list of platforms that we build for.
GO_OS_ARCH = (
    ("linux", "amd64"),
    ("linux", "arm64"),
    ("darwin", "amd64"),
    ("darwin", "arm64"),
)


def RunSteps(api, props):
    checkout_dir = api.checkout.with_options(
        manifest=props.manifest,
        remote=props.remote,
        project=props.project,
    )
    revision = api.checkout.project(props.project, checkout_root=checkout_dir)[
        "revision"
    ]

    staging_dir = api.path.mkdtemp("jiri")

    with api.context(
        cwd=checkout_dir / "go/src/fuchsia.googlesource.com/jiri",
        env_prefixes={"PATH": [api.go.go_bin]},
    ):
        # Run all the tests.
        api.go.build(["./..."])
        api.go.test(["-v", "./..."])
        api.go.test(["-v", "-race", "./..."])

        for goos, goarch in GO_OS_ARCH:
            with api.context(env={"GOOS": goos, "GOARCH": goarch}):
                platform = f"{goos.replace('darwin', 'mac')}-{goarch}"

                with api.step.nest(platform):
                    args = [
                        "-o",
                        staging_dir / "jiri",
                    ]

                    if not api.buildbucket_util.is_dev_or_try:
                        build_time = api.time.utcnow().isoformat()
                        ldflags = " ".join(
                            [
                                f'-X "go.fuchsia.dev/jiri/version.GitCommit={revision}"',
                                f'-X "go.fuchsia.dev/jiri/version.BuildTime={build_time}"',
                            ]
                        )
                        args.extend(["-ldflags", ldflags])

                    args.append("./cmd/jiri")

                    # Build the package.
                    api.go.build(args)

                    api.cipd_util.upload_package(
                        f"fuchsia/tools/jiri/{platform}",
                        staging_dir,
                        pkg_paths=[staging_dir / "jiri"],
                        search_tag={"git_revision": revision},
                        repository=props.remote,
                    )

                    if not api.buildbucket_util.is_dev_or_try:
                        api.gsutil.upload(
                            "fuchsia-build",
                            staging_dir / "jiri",
                            api.gsutil.join("jiri", f"{goos}-{goarch}", revision),
                            unauthenticated_url=True,
                            ok_ret=(0, 1),
                        )


def GenTests(api):
    yield (
        api.test("ci")
        + api.buildbucket.ci_build(
            git_repo="https://fuchsia.googlesource.com/jiri",
            revision=api.jiri.example_revision,
        )
        + api.properties(
            project="jiri",
            manifest="jiri",
            remote="https://fuchsia.googlesource.com/manifest",
        )
    )
    yield (
        api.test("cq")
        + api.buildbucket.try_build(git_repo="https://fuchsia.googlesource.com/jiri")
        + api.properties(
            project="jiri",
            manifest="jiri",
            remote="https://fuchsia.googlesource.com/manifest",
        )
    )
