# Copyright 2017 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 Go toolchain."""

from recipe_engine.recipe_api import Property

DEPS = [
    "fuchsia/buildbucket_util",
    "fuchsia/checkout",
    "fuchsia/git",
    "fuchsia/go",
    "fuchsia/macos_sdk",
    "fuchsia/upload",
    "recipe_engine/buildbucket",
    "recipe_engine/cipd",
    "recipe_engine/context",
    "recipe_engine/file",
    "recipe_engine/path",
    "recipe_engine/platform",
    "recipe_engine/step",
]

PROPERTIES = {
    "platform": Property(kind=str, help="CIPD platform for the target", default=None),
}

# Files and directories to clean up before and after a build, mirroring what go
# itself does for a release.
# See https://github.com/golang/build/blob/6c34d49dff4864185cb351d06518ce3a76efb6a2/cmd/release/release.go#L240:L248
PREBUILD_CLEAN_FILES = [
    ".gitattributes",
    ".gitignore",
    ".hgignore",
    ".hgtags",
    "misc/dashboard",
    "misc/makerelease",
]
PREBUILD_CLEAN_DIRS = [
    ".git",
    ".github",
]
# See https://github.com/golang/build/blob/6c34d49dff4864185cb351d06518ce3a76efb6a2/cmd/release/release.go#L464:L467
POSTBUILD_CLEAN_FILES = [
    "VERSION.cache",
]
POSTBUILD_CLEAN_DIRS = [
    "pkg/bootstrap",
]

FUCHSIA_THIRD_PARTY_GO_REPO = "https://fuchsia.googlesource.com/third_party/go"


def RunSteps(api, platform):
    # TODO: factor this out into a host_build recipe module.
    host_platform = "%s-%s" % (
        api.platform.name.replace("win", "windows"),
        {"intel": {32: "386", 64: "amd64",}, "arm": {32: "armv6", 64: "arm64",},}[
            api.platform.arch
        ][api.platform.bits],
    )
    target_platform = platform or host_platform

    go_dir = api.path["start_dir"].join("go")
    build_input = api.buildbucket.build.input
    if build_input.gerrit_changes:
        cl = build_input.gerrit_changes[0]
        revision = api.git.checkout_cl(cl, path=go_dir, rebase_merges=True)
    else:
        revision = api.git.checkout(
            FUCHSIA_THIRD_PARTY_GO_REPO, path=go_dir, ref="HEAD",
        )

    cipd_os, cipd_cpu = target_platform.split("-")
    goos = cipd_os.replace("mac", "darwin")
    goarch = cipd_cpu.replace("armv6", "arm")
    env = {"GOOS": goos, "GOARCH": goarch, "GOROOT_BOOTSTRAP": api.go.go_root}

    with api.macos_sdk(), api.context(cwd=go_dir.join("src"), env=env):
        with api.step.nest("pre-build file removal"):
            for filename in PREBUILD_CLEAN_FILES:
                api.file.remove(filename, go_dir.join(filename))
            for dirname in PREBUILD_CLEAN_DIRS:
                api.file.rmtree(dirname, go_dir.join(dirname))

        api.step("build", [go_dir.join("src", "make.bash")])

        if host_platform == target_platform:
            with api.context(env_prefixes={"PATH": [go_dir.join("bin")]}):
                run_bash = go_dir.join("src", "run.bash")
                api.step("test", [run_bash, "--no-rebuild"])

    # Remove after testing, as some tests may rely on the contents.
    with api.step.nest("post-build file removal"):
        for filename in POSTBUILD_CLEAN_FILES:
            api.file.remove(filename, go_dir.join(filename))
        for dirname in POSTBUILD_CLEAN_DIRS:
            api.file.rmtree(dirname, go_dir.join(dirname))

    if api.buildbucket_util.is_tryjob:
        return

    go_version = api.file.read_text(
        "read go version", go_dir.join("VERSION"), test_data="go1.8"
    ).strip()
    assert go_version, "Cannot determine Go version"

    api.upload.cipd_package(
        "fuchsia/go/" + target_platform,
        go_dir,
        [api.upload.DirectoryPath(go_dir)],
        {"git_revision": revision},
        repository=FUCHSIA_THIRD_PARTY_GO_REPO,
        extra_tags={"version": go_version},
    )


def GenTests(api):
    def props(platform):
        return {
            "platform": platform,
            "checkout.project": "integration",
            "checkout.manifest": "third_party/go",
            "checkout.remote": "https://fuchsia.googlesource.com/third_party/go",
        }

    def name(platform):
        return api.platform.name(platform.split("-")[0])

    for platform in ("linux-amd64", "linux-arm64", "mac-amd64"):
        yield (
            api.checkout.test(platform, properties=props(platform), tryjob=False)
            + name(platform)
        )
        yield (
            api.checkout.test(platform + "_cq", properties=props(platform), tryjob=True)
            + name(platform)
        )
        yield (
            api.checkout.test(
                platform + "_new", properties=props(platform), tryjob=False
            )
            + name(platform)
            + api.step_data(
                "cipd.cipd search fuchsia/go/"
                + platform
                + " git_revision:"
                + "deadbeef",
                api.cipd.example_search("fuchsia/go/" + platform, []),
            )
        )
